.AsExpandable 在 Linq to Entity

Posted

技术标签:

【中文标题】.AsExpandable 在 Linq to Entity【英文标题】:.AsExpandable in Linq to Entity 【发布时间】:2015-08-20 11:34:44 【问题描述】:

在 Linq to Entity 中,.AsExpandable() 究竟做了什么?在哪里以及为什么要使用它?它是否将所有相关实体都包含在查询中以进行延迟加载?

【问题讨论】:

AsExpandable 不是内置的 Ling 功能。如果您在谈论来自 LinqKit 的扩展方法,请阅读文档以及所基于的 blog。 非常感谢。它有帮助。 【参考方案1】:

Entity Framework 的查询处理管道无法处理调用表达式,这就是您需要在查询中的第一个对象上调用 AsExpandable 的原因。通过调用 AsExpandable,您可以激活 LINQKit 的表达式访问者类,该类将调用表达式替换为 Entity Framework 可以理解的更简单的构造。Josef Albahari

有关更多详细信息,我建议阅读author of LinqPad

【讨论】:

这在今天的 EF Core 中是否仍然相关? 我也想知道在使用 EF Core 时是否仍然需要调用 AsExpandable(),因为它不会抛出并且似乎工作得很好。 @BrunoSantos 虽然它确实不会在 EF Core 中抛出异常,但它会从数据源中检索所有数据,然后尝试在客户端执行表达式,这是低效的.所以,是的,你仍然需要像 LinqKit 这样的东西。 那么 AsExpandable 做了什么?如果我已经是 Entity Framework 方面的专家,我就不会查找这个了... @Gerry EF 查询翻译通过遍历查询表达式树并针对一组硬编码的 SQL 翻译查找每个方法,这些翻译大多是 LINQ 的子集。结果,EF 不知道 LinqKit .Invoke() 方法的实际含义,也不知道如何翻译它。 .AsExpandable()(和 .Expand())所做的是遍历表达式树,并在 EF 到达之前将 .Invoke() 的任何实例与其调用的实际表达式树交换。这样,EF 只能看到没有.Invoke()s 的“普通”表达式树。【参考方案2】:

没有从方法组到表达式(对应的委托类型)的隐式转换。从方法组到匹配签名的委托存在隐式转换。因此只有 IEnumerable 重载匹配。

当然,这并不是说您需要使用 lambda。随便写:

ctx.Set().AsExpandable().Where(ByName); 由于您正在传递一个表达式(毕竟,ByName 已经是一个表达式,这正是 Queryable.Where 所需要的),这将作为一个查询进行评估,而不是在 linq 中对对象进行评估。

【讨论】:

以上是关于.AsExpandable 在 Linq to Entity的主要内容,如果未能解决你的问题,请参考以下文章

我如何修复“LINQ to Entities无法识别方法”错误

LINQ to Entities does not recognize the method , and this method cannot be translated into a store e

Linq To SQL和Linq To Object的批量操作InsertAllOnSubmit介绍

Linq to sql - 删除,如果失败继续

对于不支持子查询的 NHibernate-to-LINQ 是不是有任何解决方法?

使用 sdf 文件的 Linq to SQL 异常