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

The LINQ expression could not be translated (Generic class)

我在 SO 上看到了很多这样的问题,但是其中 none 确实对我有帮助,所以我决定 post 另一个问题,尝试修复我的问题。

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

当我尝试使用 Predicate<T> 创建用于查询的自定义方法时出现了问题。 这是我的代码:

        public IEnumerable<T> GetMatching(Predicate<T> condition)
             => dbContext.Set<T>.Where(entity => condition(entity));

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

这是我尝试通过使用名为 EmployeeID:

的字段过滤来获取一些 Doctor 对象的部分
Repository.GetMatching(doctor => doctor.EmployeeID > 10);

我的想法是,返回一份医生列表,其中 EmployeeID 数字字段大于 10。 不幸的是,这给了我以下错误:

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().

根据错误信息,我尝试在GetMatching()函数的末尾添加ToList(),但仍然失败,同样的错误信息。

我错过了什么?

Expression<Func<T, bool>> 而不是 Predicate,然后直接传入:

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

原因是 Entity Framework 依赖表达式树来确定如何将 LINQ 代码转换为 SQL 查询。当它正在评估的表达式(你传递给 Where 的 lambda)调用一个 Entity Framework 不知道如何翻译的函数(就像有人传递给你的函数的任意委托)时,它会阻塞。

附带说明一下,请注意以下事实:返回 IEnumerable<T> 会使添加到返回值的任何其他 LINQ 代码都被视为 LINQ-to-Objects,而不是被 Entity Framework。如果这是您想要的,请考虑调用 .ToList() 并返回类似 IReadOnlyCollection<> 的内容以避免不必要地延迟执行。如果没有,考虑返回 IQueryable<>.