选择dons';我不在IQueryable上工作,但在IList上工作

本文关键字:工作 IQueryable IList 但在 dons 选择 | 更新日期: 2023-09-27 17:58:37

我有两行代码,一行是

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();

唯一的区别是在Where语句之后调用的第二个语句ToList()。第二种说法很好。

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

您可以在(方法:GetBestQualityInHistory)中查看有问题的文件的完整来源

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

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

选择dons';我不在IQueryable上工作,但在IList上工作

如果SubSonic的工作方式与Entity框架相同,则不能使用带参数的构造函数-必须使用无参数的构造函数和初始化器。我对此的高级解释是,查询不是按原样执行的——它被转换为SQL,因此您必须使用属性初始值设定项,以便表达式树知道投影类型中的哪些属性应该由值填充。当使用带参数的构造函数时,表达式树不知道传递的参数属于哪里(它不检查构造函数的内容)。一旦执行Tolist并将结果集具体化为QuantityType实例,就会调用真正的构造函数(无参数)。

这不是一个真正的答案,我本来打算把它作为一个注释,但需要更多的空间来放置代码片段

从SubSonic代码来看,我非常确信,在某些情况下,如果您遇到"不支持构造函数"的错误,SS会出于某种原因试图将new ...()语句解析为SQL。有问题的方法是SQL格式化程序的一部分,看起来它只处理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其中(data=>data.CreatedDate<=新日期时间(2011,12,01)).选择(数据=>数据)

然后newDateTime将被转换为SQL。因此,无论你如何改变林克以获得例外,我认为这就是正在发生的事情。我认为这是因为,如果在.Select()的之后添加.OrderBy(),则不再对AllItems()返回的IQueryable调用OrderBy,而是尝试根据返回的内容进行排序。Select(),它是新的Quality对象的可枚举对象,因此SS可能会尝试将所有这些转换为SQL。

我想知道如果你把它倒过来,它是否会正常工作?

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