gpt4 book ai didi

linq-to-entities - LINQ to Entities 不支持 LINQ 表达式节点类型 'Invoke'

转载 作者:行者123 更新时间:2023-12-03 23:38:26 25 4
gpt4 key购买 nike

public CategoryViewModel GetSingle( Expression<Func<CategoryViewModel, bool>> where)
{
Expression<Func<DAL.EntityModels.Category, CategoryViewModel>> converter =
c => ToBll(c);

var param = Expression.Parameter(typeof(DAL.EntityModels.Category), "category");
var body = Expression.Invoke(where, Expression.Invoke(converter, param));
var lambda = Expression.Lambda<Func<DAL.EntityModels.Category, bool>>(body, param);

return (CategoryViewModel )_categoryRepository.GetSingle(lambda);
}

代码 _categoryRepository.GetSingle(lambda) 引发异常:“LINQ to Entities 不支持 LINQ 表达式节点类型“Invoke””

是否有简单方法可以避免此异常?我不想使用其他工具,例如 LinqKit 或 PredicateBuilder。

最佳答案

这涉及到 Linq2Entities 背后的一些管道以及 Linq2Objects 和 Linq2AnythingElse 之间的差异...

您显然对表达式树有很好的理解,并且您正在以编程方式生成它们。 Linq2Entities 获取该表达式树并尝试将其转换为 SQL 查询以在数据库服务器上运行。但是,它无法将任意 C# 代码映射到其 SQL 等效项(例如,toBll 调用在 SQL 中完全没有意义)。

换句话说,您遇到此问题是因为 Linq2Entities 试图将您的 toBll 调用映射到 SQL,并且由于没有此类等效项而惨败。您尝试做的事情存在一些设计缺陷。我假设您正在尝试获取以“where”表示的任意条件以在数据库服务器上运行。但是,您的任意条件是根据您的业务层对象而定的,SQL Server 和 Entity Framework 都不了解这些对象。

对于这种设计,您真正需要做的是使用 Linq2Entities 类型(而不是 BLL 类型)来表示任意条件。由于 Linq2Entities 了解这些类型,因此它将能够将任意表达式转换为 SQL(因为它具有 Linq2Entities 类型到其 SQL 等效项的映射)。

我上面描述的确实是执行此操作的正确方法,或者,您可以枚举查询(将执行),然后针对返回的结果集运行条件。由于此时您正在 Linq2Objects 中运行(这只是针对内存中对象运行的标准 .NET 代码),因此您的函数将正常运行。但是,这意味着您的“where”子句将在内存中运行,而不是在数据库服务器上运行,所以我真的不推荐这样做

编辑:OP请求的代码...

为了使其正常工作,您需要更改 GetSingle 方法以采用作用于 EntityFramework 类型而不是 BLL 类型的表达式条件。然后,您可以从表达式树中删除转换器子句,并且您应该可以启动并运行:

public CategoryViewModel GetSingle( Expression<Func<DAL.EntityModels.Category, bool>> where)
{

var param = Expression.Parameter(typeof(DAL.EntityModels.Category), "category");
var body = Expression.Invoke(where, param);
var lambda = Expression.Lambda<Func<DAL.EntityModels.Category, bool>>(body, param);

return ToBLL((DAL.EntityModels.Category)_categoryRepository.GetSingle(lambda));
}

这种方法的问题在于,您的表达式必须采用 EntityFramework 类型,这可能会违反您隐藏数据抽象层详细信息的愿望。到那时,运气就很差了,EntityFramework + BLL + 动态查询生成 = 很难做到正确

关于linq-to-entities - LINQ to Entities 不支持 LINQ 表达式节点类型 'Invoke',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5147444/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com