c# - 如何在 .NET Core 3.0 Entity Framework 中执行组加入?
问题描述
随着对 .NET Core 3.0 的更改,我得到了
... NavigationExpandingExpressionVisitor' 失败。这可能表示 EF Core 中的错误或限制。有关更多详细信息,请参阅 https://go.microsoft.com/fwlink/?linkid=2101433 。)---> System.InvalidOperationException:处理 LINQ 表达式 'GroupJoin,...
这是一个非常简单的查询,因此必须有一种方法可以在 .NET CORE 3.0 中执行它:
var queryResults1 = await patients
.GroupJoin(
_context.Studies,
p => p.Id,
s => s.Patient.Id,
(p, studies) => new
{
p.DateOfBirth,
p.Id,
p.Name,
p.Sex,
Studies =studies.Select(s1=>s1)
}
)
.AsNoTracking().ToListAsync();
我基本上是在寻找一个 Linq 查询(或上面的方法语法),它将研究连接到患者,如果给定患者没有研究,则将研究设置为空列表或 null。
有任何想法吗?这在 .NET Core 2.2 中有效。上面的 MSFT 链接还提到,关键的重大更改与客户端评估有关,并避免生成的查询读取整个表,然后必须加入或过滤客户端。然而,通过这个简单的查询,连接应该在服务器端很容易实现。
解决方案
正如这里所讨论的,您正在尝试数据库不支持的查询。EF Core 2 使用客户端评估来使您的代码工作,但 EF Core 3 拒绝,因为随着数据集的增加,客户端的便利性是以难以调试的性能问题为代价的。
您可以使用 useDefaultIfEmpty
离开加入患者的研究,然后使用 手动分组ToLookup
。
var query =
from p in db.Patients
join s in db.Studies on p.Id equals s.PatientId into studies
from s in studies.DefaultIfEmpty()
select new { Patient = p, Study = s };
var grouping = query.ToLookup(e => e.Patient); // Grouping done client side
上面的示例抓取了完整的 Patient 和 Study 实体,但您可以选择选择列。如果您需要的 Patient 数据太大而无法为每个 Study 重复,则在连接查询中仅选择 Patient ID,在单独的非连接查询中查询其余的 Patient 数据。
推荐阅读
- php - 如何使这个 docker 图像更小?
- android - 在原生 android 应用程序中集成多个统一游戏
- c# - 从 switch 中隔离并仅使用一个 case 以仅使用一个 trackbar
- css - 如何在 png 图像上制作圆形阴影
- haskell - 有没有办法让这种类型的家庭内射?
- javascript - 更改反应路由器中的状态
- kubernetes - GKE LimitRange 将默认 cpu 限制为 100m
- php - 将提交的 XML 数据显示到文本字段中
- javascript - JavaScript - 从列表中更改两个元素的值
- python - 如何在字符串中的两个单词之间添加空格,以便总字符串长度具有特定值