C# AsExpandable()的奇怪Linq到实体行为
考虑以下C# AsExpandable()的奇怪Linq到实体行为,c#,linq,linq-to-entities,entity-framework-6,linqkit,C#,Linq,Linq To Entities,Entity Framework 6,Linqkit,考虑以下人员实体: public class Person { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } } 使用以下表达式(使用PredicateBuilder构建)作为标准: var byName = PredicateBuilder.True<Person>().And(x => x.
人员
实体:
public class Person
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
使用以下表达式
(使用PredicateBuilder构建)作为标准:
var byName = PredicateBuilder.True<Person>().And(x => x.FirstName == "Chaim");
但是,当使用这种稍有不同的语法调用时,不涉及SQL,其中
,过滤是由Enumerable完成的。其中
:
ctx.Set<Person>().AsExpandable().Where(byName.Invoke);
ctx.Set().AsExpandable().Where(byName.Invoke);
有什么想法吗?没有从方法组到表达式的隐式转换(对应的委托类型)。存在从方法组到匹配签名的委托的隐式转换。因此,只有IEnumerable
重载匹配
当然,这并不是说你需要使用lambda。只要写下:
ctx.Set<Person>().AsExpandable().Where(ByName);
ctx.Set().AsExpandable().Where(ByName);
由于您正在传递一个表达式(ByName
毕竟是一个表达式
,这正是Queryable.Where
所需要的),因此这将作为一个查询进行计算,而不是以linq对对象进行计算。有趣。你基本上是说,ByName.Invoke
是Func
然后只匹配IEnumerable.Where
,而x=>ByName.Invoke(x)
是表达式,然后匹配IQueryable.Where
?@haim770x=>ByName.Invoke(x)
,作为lambda,可以匹配任何一个。它可以是表达式,也可以是委托。因此,Queryable.Where
和Enumerable.Where
都是有效的选项,它将使用一种更好的算法<代码>可查询
获胜ByName.Invoke
,与其他任何方法组一样,只是一个方法组,不能转换为表达式
,因此可枚举。其中
是唯一可能的有效重载。我明白了。选择“更好的算法”是在运行时执行的吗?怎么做?@haim770它是在编译时完成的。有关详细信息,请参阅过载解决方案的规范。这是非常危险的。我调用了Where(expression.Compile())
而不是Where(x=>expression.Invoke(x))
。然后,在跟踪我们的生产数据库时,我看到从表中选择[each column]
;无where子句。前者来自文档!
ctx.Set<Person>().AsExpandable().Where(ByName);