4

我有两行代码,一个是

AllItems().Where(c => c.Id== id)
          .Select(d => new Quality(d.QualityType)).ToList();

和另一个

AllItems().Where(c => c.Id== id).ToList()
          .Select(d => new Quality(d.QualityType)).ToList();

唯一的区别是第二条语句ToList()是在语句之​​后调用的Where。第二条语句工作得很好。

在第一条语句中,默认的无参数构造函数被命中,而不是带有参数的构造函数。因此创建了列表,但列表中的对象使用默认值而不是 d.QualityType 进行初始化。

您可以在(方法:GetBestQualityInHistory)查看相关文件的完整来源

https://github.com/kayone/NzbDrone/blob/master/NzbDrone.Core/Providers/HistoryProvider.cs

**编辑:经过进一步调查,这似乎是一个亚音速错误,如果 LastToListOrderBy亚音速替换,则会抛出The construtor 'Void .ctor(NzbDrone.Core.Repository.Quality.QualityTypes, Boolean)' is not supported.

4

2 回答 2

4

If SubSonic works in the same way as Entity framework you cannot use constructors with parameters - you must use parameterless constructors and initializers. My very high level explanation of this is that the query is not executed as is - it is translated to SQL and because of that you must use property initializers so that expression tree knows which properties in the projected type should be filled by values. When using constructor with parameters, expression tree doesn't know where the passed parameter belongs to (it doesn't check content of the constructor). The real constructor (parameterless) is called once you execute Tolist and result set is materialized into QuantityType instances.

于 2011-06-05T19:50:23.320 回答
0

这不是一个真正的答案,我打算将其作为评论,但需要更多的代码片段空间。

从 SubSonic 代码来看,我很确定在某些情况下您会收到“不支持构造函数”错误,SS 出于某种原因试图将您的new ...()语句解析为 SQL。有问题的方法是 SQL Formatter 的一部分,看起来它只处理 DateTime:

    protected override NewExpression VisitNew(NewExpression nex)
    {
        if (nex.Constructor.DeclaringType == typeof(DateTime))
        {
            // ...omitted for brevity...
        }
        throw new NotSupportedException(string.Format("The construtor '{0}' is not supported", nex.Constructor));
    }

我认为如果您执行以下操作通常会受到影响:

someData .Where(data => data.CreatedDate <= new DateTime(2011, 12, 01)) .Select(data => data)

然后newDateTime将其转换为 SQL。因此,无论您如何更改 Linq 以获得该异常,我认为这就是正在发生的事情。我认为这是因为如果您在.OrderBy() 之后添加一个,.Select()那么您将不再在 AllItems() 返回的任何 IQueryable 上调用 OrderBy,而是尝试按 .Select() 返回的内容进行排序,这是新的质量对象,因此 SS 可能会尝试将所有这些转换为 SQL。

我想知道如果你反转它是否会正常工作?

AllItems().Where(c => c.Id== id)
      .OrderBy(d => d.QualityType)
      .Select(d => new Quality(d.QualityType));
于 2011-06-06T18:11:30.650 回答