c# - LINQ 实体框架查询在 EF Core 中不起作用,引发异常
问题描述
我有这个在旧应用程序中工作的实体框架 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 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,
}
);
推荐阅读
- javascript - VueJs CreateElement() 插入动态 html
- scala - spark解析不正确的时间戳csv
- python - 树莓派 3 上的 Python
- openmp - 使用 OpenMP 并行化 Cython 中的问题
- python - 将浮点值舍入到间隔限制/网格
- javascript - 正则表达式在数组中查找对
- sql - 从表有 > 0 行的 all_tab_columns 中选择
- javascript - 动态参考
- cron - crontab 文件中的错误
- android - 是否可以将子集合添加到集合而不在 android 的 firestore 中创建文档?