表达式 - 无法识别的方法

本文关键字:方法 识别 表达式 | 更新日期: 2023-09-27 17:55:19

如何在 linq to 实体框架的实体中执行以下操作:

public static Expression<Func<T, bool>> IsOk<T>(long? entityId)
{
  return x => (!entityId.HasValue || entityId.Value == x.GetEntityId());
 }

x.GetEntityId()返回异常,因为它无法识别该方法。

表达式 - 无法识别的方法

我建议将类型参数限制为自定义接口,例如 IMyExpectation 包含

interface IMyExpectation {
     int GetEntityId();
}

然后将方法的类型参数限制为该接口。(现在,这将按照GetEntityId方法进行编译。

public static Expression<Func<T, bool>> IsOk<T>(long? entityId) 
       where T: IMyExpectation // << restrict the type to what is needed
{
  return new Func<T, bool>(
        x => !entityId.HasValue || entityId.Value == x.GetEntityId() 
  );
}

然后在实体框架上,类在需要的地方实现该接口,但在单独的文件中partial类的一部分上实现该接口,以便模型不会在重新生成模型时擦除自定义代码。

例如

在 EF 模型实体
注意:这取决于Aliostad的回答。

public partial class Customer : IMyExpectation { //...
public partial class Invoice : IMyExpectation { //....
// etc

或者,在您的 POCO
注意:如果不受 EF 类的阻碍,这应该可以正常工作

public class CustomerPoco: IMyExpectation { //...
public class InvoicePoco : IMyExpectation { //...

现在,您的实体和类(以及您在其上实现"IMyExpectation"的任何内容)都按照原始方法的意愿表达自己。
最后,您的方法将理解您实现接口的任何这些内容,因此它们都是通过其类型参数传递给该方法的候选者。

如果你的场景是这个答案的正确场景,那么这应该很好地结束了。

你不能 - 你的数据库不能GetEntityId()运行(因为它不理解它),因此你的 Linq 提供程序无法翻译它。


更新

那么如何解决它:

  • Id 必须是实体上的属性,因此映射到数据库中的列。这样它可以很容易地在表达式中使用
  • 如果计算了 Id(GetEntityId() 中有逻辑),那么这需要在客户端完成:返回所有行并随后在 C# 中进行过滤。当然,不用说它会对你的表现产生什么影响。