C# LINQ表达式';DbSet<;实体>;。式中(p=>;p.IsValid)&x27;无法在EF Core 3中翻译
首先,我知道EF Core 3中的突破性变化,如中所述 但是我仍然有点困惑,为什么下面的代码不起作用:C# LINQ表达式';DbSet<;实体>;。式中(p=>;p.IsValid)&x27;无法在EF Core 3中翻译,c#,entity-framework-core,C#,Entity Framework Core,首先,我知道EF Core 3中的突破性变化,如中所述 但是我仍然有点困惑,为什么下面的代码不起作用: var posts = await _applicationDbContext.Posts .Include(p => p.Account) .Include(p => p.Recording) .Where(p => p.AccountId == accountId && p.Type
var posts = await _applicationDbContext.Posts
.Include(p => p.Account)
.Include(p => p.Recording)
.Where(p => p.AccountId == accountId && p.Type == postType && p.IsValid)
.OrderByDescending(p => p.Occured)
.ToListAsync();
抛出异常
System.InvalidOperationException:LINQ表达式“DbSet”
。其中(p=>p.AccountId==\uuuuu AccountId\u0&&(int)p.Type==(int)\uuuuu postType\u1&&p.IsValid)“”无法翻译。以可以翻译的形式重写查询,或者通过插入对AsEnumerable()、AsAsAsAsyncEnumerable()、ToList()或ToListSync()的调用显式切换到客户端计算。有关更多信息,请参阅
IsValid的实施情况如下:
public bool IsValid => Status == PostStatus.Active && Recording.IsValid
public bool IsValid => Status == RecordingStatus.Active;
现在,如果我将查询更改为:
var posts = await _applicationDbContext.Posts
.Include(p => p.Account)
.Include(p => p.Recording)
.Where(p => p.AccountId == accountId && p.Type == postType && p.Status == PostStatus.Active && p.Recording.Status == RecordingStatus.Active)
.OrderByDescending(p => p.Occured)
.ToListAsync();
它可以正常工作,并按预期转换为sql。当然,我可以使用第二个实现,但是在一个地方使用IsValid实现有明显的优势。我也不想跳过查询中的IsValid检查,而希望稍后在内存中进行检查,原因很明显。我在这里遗漏了什么吗?我仍然认为EF的人可以采取不同的做法,但无论如何,从上面Progman链接到的评论中,可以得出一个类似以下内容的解决方法:
public static Expression<Func<Post, bool>> IsValid => post => post.Status == PostStatus.Active && post.Recording.Status == RecordingStatus.Active;
这样可以避免代码重复,并在一定程度上遵循良好的做法。请将您的问题包含在您收到的完整错误消息中。@Progman。这是否回答了您的问题?在第一种情况下,EF-Core不知道
IsValid
property getter做什么(你能不能只看一个没有源代码的类?)。因此,他们唯一的选择是在创建对象后对其进行局部求值,但这在3.0+中被删除。好吧,我想对我来说,这样做没有什么意义。类及其实现就在这里,您还可以使用它。至于第二个实现,如果我想更改IsValid检查,我需要在多个地方进行更改,修改代码等。即使在与查询相同的类中创建私有方法,也会产生相同的错误。
var posts = await _applicationDbContext.Posts
.Include(p => p.Account)
.Include(p => p.Recording)
.Where(p => p.AccountId == accountId && p.Type == postType)
.Where(Post.IsValid)
.OrderByDescending(p => p.Occured)
.ToListAsync();