c# - 使用 Entity Framework 如何在没有大量查询结果集或数百个小查询的情况下创建嵌套对象?
问题描述
我正在使用 EF 填充对象,然后在我的业务层代码中与之交互。这些对象有几个级别,但让我们首先将其简化为一个典型的主从示例,使用Order
和OrderLine
。
假设我需要检索 50 个订单,每个订单大约有 100 个订单行,并且我需要所有这些数据。在 EF 中执行此操作的最有效方法是什么?
如果我这样做:
var orders = context.Orders.Where(o => o.Status == "Whatever")
.Include(order => order.OrderLines)
.ToList();
然后它会运行一个查询来拉回 50x100 行,然后它巧妙地将其组合成 50 个Order
对象,每个对象都有自己的OrderLine
对象。
相反,如果我不这样做,Include()
然后我会遍历每个Order
和它的OrderLines
,那么它将发出 50 个单独的查询来获取OrderLine
数据,即每个查询一个Order
。
到目前为止,这.Include()
似乎很棒:我从 SQL 中提取的数据比需要的多一点,但这比发出 50 个额外的查询要好得多。但是有没有办法我可以选择发出 2 个查询,一个 getOrder
一个 get OrderLine
,并让 EF 自动连接对象?
我想要的更现实的情况是数据更复杂。假设我想要这样的对象(在哪里Product
买的东西是OrderLine
用来ProductPart
制作的Product
):
- Order
- OrderLine (avg 100 per Order)
- Product (1 per OrderLine)
- ProductPart (avg 20 per Product)
现在,如果我使用.Include()
with ProductPart
,它会使查询结果更大。或者,如果我不这样做Include()
,它将为每个Product
.
有没有第三种方法可以让我获得一个查询中的所有Order
,OrderLine
和Product
数据以及另一个查询中的所有ProductPart
数据,并神奇地让 EF 为我连接对象?
更新:
我刚刚读到AsSplitQuery()
这似乎是我正在寻找的,但仅在 EF Core 5 中可用,直到 2020 年 11 月才稳定(?)。我正在寻找一种在 EF6 中实现这一目标的方法。
进行更多研究,我发现https://entityframework.net/improve-ef-include-performance当您有多种对象类型从父对象脱落时,它建议了两种方法:
执行多个 EF 命令以拉回相同的父对象列表,但每次都使用
Include()
不同的子对象类型。显然,EF 将连接它已经从数据库中提取的相关对象。使用似乎可以执行类似操作的 EF+ 库
AsSplitQuery()
我不确定这是否适用于我的情况,即嵌套层次更多,而不仅仅是父对象之外的不同类型的对象。我的猜测是肯定的,如果我很聪明的话。有小费吗?
解决方案
这样的事情可能会破坏您的对象结果,但应该执行两个单独的查询。
var ordersQuery = context.Orders.Where(o => o.Status == "Whatever");
var orderLineGroups = ordersQuery
.SelectMany(o => o.OrderLines)
.ToLookup(l => l.OrderID); // <- Not sure what your FK name is
var orders = ordersQuery.Select(o => new {
Order = o,
OrderLines = orderLineGroups[o.Id]
}).ToList();
推荐阅读
- sanity - 错误:在插件“@sanity/base”中找不到“sanity.json”文件
- flutter - 如何从新的持续时间重新启动 AnimationControler
- shell - 复制神器CURL中的最新神器
- flutter - 显示 CircularProgressBar 时控制页面视图滚动
- javascript - 从javascript中删除父节点
- php - Yii2 视图未渲染。返回主视图
- javascript - 响应式菜单 (mmenu) 导致高 CLS
- c# - 为什么 fastJSON 反序列化在单元测试中完成,但一个属性及其属性在活动时未填充?
- unity3d - 用户可以在 Agora Unity SDK 中同时加入多个视频频道吗?
- ios - Xamarin iOS Shell FlyoutMenu 无法正确呈现