选择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
**编辑:经过进一步调查,如果最后一个ToList
被OrderBy
替换,这似乎是一个亚音速错误,亚音速抛出The construtor 'Void .ctor(NzbDrone.Core.Repository.Quality.QualityTypes, Boolean)' is not supported
。
如果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));