在LINQ查询网络核心3中使用函数逻辑

问题描述 投票:0回答:1

我有以下枚举:

      public enum WorkType
      {
        Type1,
        Type2,
        Type3,
        Type4,
        Type5,
        Type6
       }

和一个班级

      public class Work {
        public WorkType Type {get; set;}
        ....
      }

和扩展方法:

    public static partial class WorkTypeExtensions
    {
      public static bool IsHighValueWork(this WorkType value)
      {
        switch (value)
        {
            case WorkType.Type1:
            case WorkType.Type2:
                return true;

            default:
                return false;
        }
      }
    }

和SQL Linq查询

  public List<Work> GetHighValueWork()
  {
    var query = Context.Work.Where( w => w.IsHighValueWork());
    return query.ToList();
   }

这是我的问题的简化版本。该查询曾经有效,但是在将代码从net core 2.1转换为3.1之后,它不再起作用。错误消息是该查询无法翻译。以一种可以翻译的形式重写查询,或者通过插入对AsEnumerable(),AsAsyncEnumerable()的调用来显式切换到客户端评估。我不想将其更改为

 public List<Work> GetHighValueWork()
  {
    var query = Context.Work.Where( w => w.Type == WorkType.Type1 || w.Type == WorkType.Type2);
    return query.ToList();
   }

因为实际功能非常复杂。我搜索了似乎可以使用LINQ Expression Func,但是我还没有想到。做这个的最好方式是什么?

c# .net-core linq-to-sql linq-to-entities
1个回答
1
投票

link中确实得到了很好的解释,为什么它可以在.net core 2.1中运行。似乎,在以前的版本中,当EF Core无法将作为查询一部分的表达式转换为SQL或参数时,它会自动在客户端上评估该表达式。

这真的很糟糕。因为,如上所述:

例如,Where()调用中无法转换的条件可能导致表中的所有行从数据库服务器,以及要在客户端上应用的过滤器。因此,似乎以前您只是将所有数据加载到客户端,然后在客户端应用过滤器。

因此,您的代码存在的问题是,Func无法转换为Sql。要么将所有数据显式提取到应用中,然后进行过滤,要么使用第二版代码。

Context.Work.ToList()
       .Where( w => w.IsHighValueWork());

但是,我不建议使用该版本。最好使用第二个版本。但是,您可以在枚举中使用标志,以使代码更具可读性和可维护性。

© www.soinside.com 2019 - 2024. All rights reserved.