LINQ 实体框架查询在 EF Core 中不起作用,引发异常
Posted
技术标签:
【中文标题】LINQ 实体框架查询在 EF Core 中不起作用,引发异常【英文标题】:LINQ Entity Framework query not working in EF Core, throwing exception 【发布时间】:2021-12-16 22:45:14 【问题描述】:我有这个在旧应用程序中工作的实体框架 v4.0 查询,我正在将其转换为 EF Core 版本 5.0。
当我在调试中运行代码时,它会在 .ToList(); 之后抛出以下错误
The LINQ expression 'DbSet<User>()
.GroupJoin(
inner: DbSet<Address>(),
outerKeySelector: u => u.UserId,
innerKeySelector: a => a.UserId,
resultSelector: (u, ua) => new
u = u,
ua = ua
)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
所以,我添加了 .ToList() 并且还尝试了 .ToListAsync() 到查询的末尾,但是这个错误仍然存在。
我查看了 docs.microsoft,发现这个示例看起来像我的查询
var query = from person in people
join pet in pets on person equals pet.Owner into gj
from subpet in gj.DefaultIfEmpty()
select new person.FirstName, PetName = subpet?.Name ?? String.Empty ;
更新:我注释掉了加入并删除了错误,但不知道为什么这不起作用。另一篇文章提到如果无法解释 linq 但附加连接看起来很简单,则会生成此错误,对吧?
var users =
(from u in this.MyDbContext.User
join a in this.MyDbContext.Address
on u.UserId equals a.UserId
into ua
//join d in this.MyDbContext.JobTitle
// on e.JobTitleId equals d.JobTitleId
from ua_left in ua.DefaultIfEmpty()
select new UserViewModel
BoardId = u.BoardId,
UserId = u.UserId,
LastName = u.LastName,
FirstName = u.FirstName,
JobTitleId = u.JobTitleId,
//JobTitle = d.JobTitleDescription,
Email = u.Email,
Grade = u.Grade,
Title = u.Title,
//StartDate = ua_left.StartDate,
);
var test = users.ToList();
我不确定我错过了什么
var users =
(from u in this.MyDbContext.User
join a in this.MyDbContext.Address
on u.UserId equals a.UserId
into ua
join d in this.MyDbContext.JobTitle
on e.JobTitleId equals d.JobTitleId
from ua_left in ua.DefaultIfEmpty()
select new UserViewModel
BoardId = u.BoardId,
UserId = u.UserId,
LastName = u.LastName,
FirstName = u.FirstName,
JobTitleId = u.JobTitleId,
JobTitle = d.JobTitleDescription,
Email = u.Email,
Grade = u.Grade,
Title = u.Title,
//StartDate = ua_left.StartDate,
);
var test = users.ToList();
在玩完代码后,如果我像这样取出左连接子句,查询将运行并返回数据
var users =
(from u in this.MyDbContext.User
join a in this.MyDbContext.Address
on u.UserId equals a.UserId
join d in this.MyDbContext.JobTitle
on e.JobTitleId equals d.JobTitleId
select new UserViewModel
BoardId = u.BoardId,
UserId = u.UserId,
LastName = u.LastName,
FirstName = u.FirstName,
JobTitleId = u.JobTitleId,
JobTitle = d.JobTitleDescription,
Email = u.Email,
Grade = u.Grade,
Title = u.Title,
//StartDate = ua_left.StartDate,
);
var test = users.ToList();
我查看了另一个帖子,其他人正在使用相同的左连接。我不确定为什么它不能在 EF Core 上运行。
感谢任何帮助。谢谢。
【问题讨论】:
请同时提及您使用的 EF Core 版本。 您的 UserViewModel 的 StartDate 属性是否可以为空?如果不是,请尝试使其可为空并执行查询。 我想你正在使用 EF Core 3+。虽然没有直接关系,但我相信这是原因***.com/questions/58074844/… - 基本上,查询评估不再在客户端完成。如果方法不能转换为 SQL(或其他)命令,那么它会抛出。如果您想接受这个作为答案,请告诉我,我会添加它(看起来是无法翻译的DefaultIfEmpty
- 您可以将第一部分加载到内存中然后再试一次)
您的查询中的e
是什么?
我注释掉了其中一个连接,错误消失了,但不知道为什么?
【参考方案1】:
虽然没有直接关系,但我相信是原因:EF Linq Error after change from dotnet Core 2.2.6 to 3.0.0
基本上,因为 EF Core 3 查询评估不再在客户端完成。这意味着,如果一个方法不能转换为 SQL 命令,它就会抛出异常。查看代码是无法翻译的DefaultIfEmpty()
。 编辑: 与into [x]
的多个连接似乎无法翻译。
您“可以”将表加载到内存中然后使用它 - 因为客户端/代码正在处理数据,而不是 EF 试图编译的 SQL 查询。但是,这会加载整个表格,这可能会非常密集 - 取决于大小。
更好的解决方案是使用空值 - 如下所示:(未测试)
var users =
(
from u in this.MyDbContext.User
join a in this.MyDbContext.Address
on u.UserId equals a.UserId
join d in this.MyDbContext.JobTitle
on e.JobTitleId equals d.JobTitleId
select new UserViewModel
BoardId = u.BoardId,
UserId = u.UserId,
LastName = u.LastName,
FirstName = u.FirstName,
JobTitleId = u.JobTitleId,
JobTitle = d.JobTitleDescription,
Email = u.Email,
Grade = u.Grade,
Title = u.Title,
StartDate =
ua == null
? System.Data.SqlTypes.SqlDateTime.MinValue
a.StartDate,
);
【讨论】:
嗨,格伦,我对您的解决方案感到困惑。在玩弄了代码之后,当我删除其中一个连接时,错误就消失了。 我想了解 EF Core 的最佳实践如何使多个 JOIN 与 outleft join 一起工作。到目前为止,此查询比旧的 v4 EF 慢。谢谢 删除into ua
修复了我的示例-这很奇怪,因为它在您留下的连接中-但我的错误与您的一致。最佳实践是另一回事——我要说的一件事是关系是要走的路——简化了很多代码。此外,如果连接列可以为空,它将始终为left join
。以上是关于LINQ 实体框架查询在 EF Core 中不起作用,引发异常的主要内容,如果未能解决你的问题,请参考以下文章