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

C# 在LINQ查询网络核心3中使用函数逻辑,c#,.net-core,linq-to-sql,linq-to-entities,C#,.net Core,Linq To Sql,Linq To Entities,我有以下枚举: public enum WorkType { Type1, Type2, Type3, Type4, Type5, Type6 } 还有一节课 public class Work { public WorkType Type {get; set;} .... } 以及一种扩展方法:

我有以下枚举:

      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();
   }
public List GetHighValueWork()
{
var query=Context.Work.Where(w=>w.IsHighValueWork());
返回query.ToList();
}
这是我问题的简化版本。此查询以前可以工作,但在代码从NETCore2.1转换为3.1后不再工作。错误消息是 无法翻译该查询。以可以翻译的形式重写查询,或者通过插入对AsEnumerable()和AsAsAsyncEnumerable()的调用显式切换到客户端计算。我不想把它改成

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

因为实际的功能非常复杂。我搜索了一下,似乎可以使用LINQ表达式Func,但我还没有想到这一点。最好的方法是什么

IsHighValueWork
只是一种简单的C#方法。无法通过EF将该函数转换为SQL

这就很好地解释了它为什么在.NETCore2.1中工作。在以前的版本中,当EF Core无法将作为查询一部分的表达式转换为SQL或参数时,它会自动在客户端计算表达式。

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

例如,Where()调用中无法转换的条件可能会导致表中的所有行从 数据库服务器和要应用于客户端的筛选器

所以,以前您似乎只是将所有数据加载到客户端,然后在客户端应用过滤器

因此,代码的问题是,
Func
无法转换为Sql。 要么显式地将所有数据提取到应用程序中并过滤,要么使用第二个版本的代码

Context.Work.ToList()
       .Where( w => w.Type.IsHighValueWork());
但是,我不建议使用那个版本。最好使用第二个版本,如下所示:

Func<Work, bool> IsHighValueWork = (work) =>
            work.Type == WorkType.Type1 || work.Type == WorkType.Type2;

你的方法行得通,会让你大吃一惊。我读了下面的文章,似乎有一种使用表达式树的方法。如果没有更好的答案,我会将您的答案标记为。@user3097695他们使用SD表达式动态构建
Func
。对你来说,这是不需要的。正如我所说,EF无法将
开关盒
转换为sql@FarhadJabiyev我可以建议您对您使用的代码段做一点小的修改吗?行
Context.Work.ToList(),其中(w=>w.IsHighValueWork())应该是
Context.Work.ToList().Where(w=>w.Type.IsHighValueWork())as扩展函数是为'WorkType'类编写的。
var query = Context.Work.Where(IsHighValueWork);