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);