我有以下内容:
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();
}这是我问题的简化版本。这个查询过去是工作的,但是在代码从NetCore2.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();
}因为实际的功能非常复杂。我搜索了似乎可以使用,但我还没有想到这一点。做这件事最好的方法是什么?
发布于 2020-01-15 23:24:25
IsHighValueWork只是一个简单的C#方法。通过EF无法将该函数转换为SQL。
这个链接很好地解释了为什么它在.net内核2.1中工作。在以前的版本中,当EF无法将查询的一部分表达式转换为SQL或参数时,会自动在客户端上计算表达式.
而且真的很糟糕。因为,如前所述:
例如,Where()调用中无法转换的条件可能导致从数据库服务器传输表中的所有行,并将筛选器应用于客户端。
因此,以前您似乎只是将所有数据加载到客户端,然后在客户端应用过滤器。
所以,您的代码的问题是,Func不能被转换成Sql。要么将所有数据显式地获取到app中,然后进行筛选,要么使用第二个版本的代码。
Context.Work.ToList()
.Where( w => w.Type.IsHighValueWork());但是,我不建议使用那个版本。最好像这样使用第二个版本:
Func<Work, bool> IsHighValueWork = (work) =>
work.Type == WorkType.Type1 || work.Type == WorkType.Type2;然后:
var query = Context.Work.Where(IsHighValueWork);https://stackoverflow.com/questions/59760914
复制相似问题