我正在摆弄linq的Func
参数(在实体框架上)。然后我发现了这种行为
var idMatchQuery = new Func<MyClass, bool>(x => x.Id == someId);
var statusMatchQuery = new Func<MyClass, bool>(x => x.Status == someStatus);
/// works
var a = myClassEntity.FirstOrDefault(idMatchQuery);
/// doesn't work
var b = myClassEntity.FirstOrDefault(p => idMatchQuery(p) && statusMatchQuery(p));
/// doesn't work
var c = myClassEntity.FirstOrDefault(p => idMatchQuery(p) && p.Status == 1);
它会抛出UnsupportedOperationException
,因为EF
无法识别这些查询。如果以上都不起作用,我可以更轻松地接受它。但是当它与一个且只有一个Func
查询一起使用时,它会让我感到烦恼,但不会与其他查询组合。
我确信有一个解释,但我猜我的搜索条件对于我正在寻找的答案来说太天真了。
这种行为的解释是什么?
答案 0 :(得分:4)
导致EF应该将您的谓词转换为TSQL语言。您可以检查FirstOrDefault
方法的参数不是Func<T, bool>
,而是Expression<Func<T, bool>>
,因为最后一个让我们有机会解析它并转换为TSQL。当您使用两个Func<T, bool>
或Func<T, bool>
条件简单时,由于Expression<Func<T, bool>>
内容和功能复杂性,EF无法将其转换并解析为TSQL,这就是为什么EF将此谓词保留为原点状态并首先发送到服务器,因此 - UnsupportedOperationException
。因此,对于EF - 解析第一个谓词比其他两个更容易。
结论:它是由从Expression<Func<T,bool>>
到TSQL的转换C#谓词的功能和方法引起的,因为它有时足够高的复杂性。