我尝试执行以下操作(SelectedIdCollection为List,cb.Id为int) -
db.Items.Where(cb => (SelectedIdCollection == null || SelectedIdCollection.Contains(cb.Id)))
基本上,如果SelectedIdCollection
为null,则返回所有内容,如果它不为null,则按其过滤。
但它会引发以下错误 -
类型' System.NotSupportedException'的例外情况发生在EntityFramework.SqlServer.dll中但未在用户代码中处理。不能 比较类型的元素 ' System.Collections.Generic.IList`1 [[System.Int32,mscorlib, Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089]]'。 只有原始类型,枚举类型和实体类型 支撑。
还有其他方法可以将这个写入条件吗?
答案 0 :(得分:4)
由于SelectedIdCollection
是从表达式外部捕获的变量,因此在创建表达式之前可以将其作为null
处理,然后将其视为非null:
var getEverything = SelectedIdCollection==null;
var targetCollection = SelectedIdCollection ?? new int[0];
var res = db.Items.Where(cb => getEverything || targetCollection.Contains(cb.Id));
现在targetCollection
保证为非null
,getEverything
标志涵盖需要从数据库中选择所有内容的条件。
答案 1 :(得分:2)
抛出异常是因为您正在比较运行时变量(SelectedIdCollection != null
),而EF并不知道如何将其转换为SQL。
你可以这样做吗?
var items = db.Items.AsQueryable();
if(SelectedIdCollection != null)
{
items = items.Where(cb => SelectedIdCollection.Contains(cb.Id));
}
if(date1 != null)
{
items = items.Where(cb => cb.Date1 == date1);
}
在SQL中这也可能更快,因为查询计划程序可能会选择不同的索引,如果它不需要读取所有要过滤的列。