LINQ表达式无法翻译(通用类)

时间:2020-11-01 22:36:33

标签: entity-framework entity-framework-core linq-to-entities

我在SO上已经看到了许多这样的问题,但是这些问题对我没有真正的帮助,所以我决定发布另一个问题,以尝试解决我的问题。

我有一个类14 作为基本GenericRepository<T>方法的模板,因为我有一个相对较大的模型包,所以我不想为不同的类实现相同的方法一遍又一遍(不要重复自己)。

当我尝试创建用于使用CRUD进行查询的自定义方法时,出现了问题。 这是我的代码:

Predicate<T>

在我看来,这样做的目的是能够传递任何类型的查询,对其进行评估并作为结果返回。

这是我尝试通过使用名为 public IEnumerable<T> GetMatching(Predicate<T> condition) => dbContext.Set<T>.Where(entity => condition(entity)); 的字段过滤某些Doctor对象来获取它们的部分:

EmployeeID

这个想法是,给我一个医生名单,这些医生的Repository.GetMatching(doctor => doctor.EmployeeID > 10); 数字字段大于10。 不幸的是,这给了我以下错误:

EmployeeID

根据错误消息,我尝试在Unhandled exception. System.InvalidOperationException: The LINQ expression 'DbSet<Doctor> .Where(d => Invoke(__condition_0, d[Doctor]))' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). 函数的末尾添加ToList(),但没有发现,它仍然失败,并显示了相同的错误消息。

我想念什么?

1 个答案:

答案 0 :(得分:1)

Predicate代替Expression<Func<T, bool>>,然后直接传递给它:

    public IEnumerable<T> GetMatching(Expression<Func<T, bool>> condition)
         => dbContext.Set<T>.Where(condition);

这样做的原因是,实体框架依赖于表达式树来确定如何将LINQ代码转换为SQL查询。当它正在评估的表达式(您传递给Where的lambda)调用一个实体框架不知道如何翻译的函数(例如有人传入您的函数的任意委托)时,它就会窒息。

请注意,返回IEnumerable<T>会使添加到返回值上的所有其他LINQ代码都被视为LINQ-to-Objects,而不是由Entity Framework进行评估,这一点应引起注意。如果您要这样做,请考虑调用.ToList()并返回类似IReadOnlyCollection<>的内容,以避免不必要的延迟执行。如果没有,请考虑返回IQueryable<>