首页 > 解决方案 > 计算的只读成员作为计算列

问题描述

我有以下课程,并希望能够使用这样的 Linq Query 来查询它dbContext.Example.Where(e=> e.IsBetween);

public class Example {
  public DateTime Start {get; set;}
  public DateTime End {get; set;}
  public bool IsBetween => DateTime.Now >= Start && DateTime.Now <= End ;
}

但是,这会在运行时导致“无法翻译 LINQ 表达式 [...]。要么重写 [...] 要么切换到客户端评估”错误。

有什么方法可以将只读属性链接IsBetween到数据库中的计算列?

标签: c#linqlinq-to-sqlentity-framework-coreef-core-3.1

解决方案


该错误表明 EF 无法将您的自定义方法(属性 getter)转换为 SQL。如果您有/想要映射IsBetween到 db 中的计算列,您应该相应地进行操作。像这样的东西(没有检查 SQL 的有效性):

public class Example {
  public DateTime Start {get; set;}
  public DateTime End {get; set;}
  public bool IsBetween {get; set;} ;
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    // your setup ...
    modelBuilder.Entity<Example>()
        .Property(p => p.IsBetween)
        .HasComputedColumnSql("getdate() >= Start AND getdate() <= END");
}

如果您只想IsBetween存在于代码中,则需要使用表达式树,或者例如:

public class Example {
  public DateTime Start {get; set;}
  public DateTime End {get; set;}
  public bool IsBetween => _func(this) ; 
  public static readonly Expression<Func<Example, bool>> IsBetweenExpr = e => 
      DateTime.Now >= e.Start && DateTime.Now <= e.End;
  private static readonly Func<Example, bool> _func = _expr.Compile();
}

dbContext.Example.Where(Example.IsBetweenExpr) ....;

推荐阅读