使用实体框架如何在没有一个庞大查询结果集或数百个小型查询的情况下创建嵌套对象?

2024-05-01

我使用 EF 填充对象,然后在业务层代码中与之交互。这些对象有多个级别,但我们首先将其简化为典型的主从示例Order and OrderLine.

假设我需要检索 50 个订单,每个订单大约有 100 个订单行,并且我需要所有这些数据。在 EF 中执行此操作最有效的方法是什么?

如果我这样做:

var orders = context.Orders.Where(o => o.Status == "Whatever")
                .Include(order => order.OrderLines)
                .ToList();

然后它会运行一个查询来拉回 50x100 行,然后它巧妙地将其组装成 50Order对象,每个对象都有自己的OrderLine对象。

如果我不这样做Include()然后我会迭代每个Order和它的OrderLines,然后它将发出 50 个单独的查询来获取OrderLine数据,即每个数据一个Order.

到目前为止.Include()看起来很棒:我从 SQL 中提取了比需要的多一点的数据,但这比发出 50 个额外查询要好得多。但是有没有一种方法可以让我选择发出 2 个查询,其中一个是获取Order和一个得到OrderLine,并且 EF 自动连接对象?

我想要的一个更现实的场景是数据更复杂。假设我想要这样的对象(其中Product是在 购买的东西OrderLine and ProductPart是用于制作的位数Product):

- Order
   - OrderLine (avg 100 per Order) 
       - Product (1 per OrderLine)
           - ProductPart (avg 20 per Product)

现在如果我做一个.Include() with ProductPart,它会让查询结果变得更大。或者如果我不这样做Include()然后它会为每个发出单独的查询Product.

有没有第三种方法可以让我获得所有Order, OrderLine and Product一次查询中的数据以及所有ProductPart另一个查询中的数据,并且 EF 神奇地为我连接对象?

UPDATE:

我刚刚读到AsSplitQuery() https://learn.microsoft.com/en-us/ef/core/querying/related-data这似乎是我正在寻找的东西,但仅在 EF Core 5 中可用,该版本直到 2020 年 11 月才稳定(?)。我正在寻找一种在 EF6 中实现此目标的方法。

更多研究,我发现https://entityframework.net/improve-ef-include-performance https://entityframework.net/improve-ef-include-performance当父对象有多个对象类型时,建议采用两种方法:

  1. 执行多个EF命令拉回相同的父对象列表,但是每次Include()- 不同的子对象类型。显然,EF 将连接它已经从数据库中提取的相关对象。

  2. 使用 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();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用实体框架如何在没有一个庞大查询结果集或数百个小型查询的情况下创建嵌套对象? 的相关文章

  • 如何知道并加载特定文件夹中的所有图像?

    我有一个应用程序 C Builder 6 0 需要知道特定文件夹中的图像总数 然后我必须加载它们 在 ImageList 或 ComboBoxEx 中 或任何其他控件中 我怎样才能做到这一点 我知道如何在控件中加载图像 或保存在 TList
  • 如何向 UWP 项目添加 .NET dll 引用?

    我有几个适用于 NETv4 x 的 NET dll 项目 我将版本更改为 4 6 1 并重新构建 没有出现问题 当我尝试从 UWP 项目向它们添加引用时 出现错误 项目的目标是 NETCore 而文件引用的目标是 NET框架 这不是受支持的
  • SQL Server 2008 中的全文搜索一步一步

    如何开始使用SQL Server 2008 中的全文搜索 阅读这些链接 SQL SERVER 2008 创建全文目录和全文搜索 http blog sqlauthority com 2008 09 05 sql server creatin
  • 实体框架代码优先 - 在另一个文件中配置

    使用 Fluent API 将表到实体的映射分开的最佳方法是什么 以便它全部位于单独的类中 而不是内联在 OnModelCreating 方法中 我目前在做什么 public class FooContext DbContext prote
  • .NET 可移植类库中的 .ToShortDateString 发生了什么

    我想知道为什么没有 ToShortDateString在 NET 可移植类库中 我有 2 个项目 Silverlight 和常规 NET 类库 使用相同的代码 并且代码涉及调用 ToShortDateString on a DateTime
  • 身份未映射异常

    System Security Principal IdentityNotMappedException 无法转换部分或全部身份引用 该错误仅在应用程序注册后出现一次 当 SecurityIdentifier 无法映射时 例如 返回 Ide
  • 字节到二进制字符串 C# - 显示所有 8 位数字

    我想在文本框中显示一个字节 现在我正在使用 Convert ToString MyVeryOwnByte 2 但是 当字节开头有 0 时 这些 0 就会被删除 例子 MyVeryOwnByte 00001110 Texbox shows g
  • 组合 Datepicker 和 Timepicker 值 Win 8.1

    我试图同时使用 Datepicker Timepicker 来返回可以存储在数据库中的 DateTime 例如 我想要安排会议的开始日期和结束日期 如果适用 我将如何将这些值组合成 SQL 数据库可以处理的正确格式 任何反馈都会很棒 我让这
  • 根据拦截和返回值自动重试客户端WCF调用

    是否可以拦截 WCF 调用的结果并重试该操作 例如 操作的返回值可能包含状态代码 指示我传递到原始调用的会话令牌已过期 在这种情况下 我可以检索新的会话令牌并使用新的会话令牌重试调用 是否可以通过使用 WCF 拦截返回值 检查它 然后以对操
  • 成员初始值设定项列表中的求值顺序是什么?

    我有一个带有一些参数的构造函数 我假设它们是按照列出的顺序初始化的 但在一种情况下 它们似乎是按相反的顺序初始化的 导致中止 当我反转参数时 程序停止中止 下面是我正在使用的语法的示例 a 之前需要初始化b 在这种情况下 你能保证这个初始化
  • 防止复制构造和返回值引用的分配

    如果我有一个函数返回对类实例的引用 但我无法控制其源 比如说list
  • 捕获当前正在播放的声音

    是否可以捕获计算机上当前播放的声音 如果能够将其保存为 mp3 就好了 但我认为这样做会存在一些法律问题 所以 wav 也可以 我环顾四周 有人建议使用虚拟音频线之类的东西 在 C 中捕获声音输出 https stackoverflow c
  • 在 SQL Server 中获取帐户“锁定”状态

    我想解锁 SQL Server 中的一个帐户 在解锁之前 我必须检查该帐户是否被锁定 我只想在帐户被锁定时解锁 是否有任何 SQL 查询或存储过程来获取 SQL 用户的 锁定 状态 代表 Alex K 发布答案 SELECT LOGINPR
  • C++ Primer 5th Edition 错误 bool 值没有指定最小大小?

    bool 的最小大小不应该是 1 个字节吗 这有点学术性的东西 尽管它们会转换为数字 并且 与其他所有事物一样 它们最终将基本上由计算机内存中的数字表示 但布尔值不是数字 你的bool可以取值true 或值false 即使您确实需要至少 1
  • 如何在 C++ 中使用 PI 常数

    我想在一些 C 程序中使用 PI 常数和三角函数 我得到三角函数include
  • 如何从枚举中选择随机值?

    给定 C 中的任意枚举 如何选择随机值 我没有找到这个非常基本的问题 我会在一分钟内发布我的答案作为任何人的参考 但请随意发布你自己的答案 Array values Enum GetValues typeof Bar Random rand
  • 用 C# 编写的带有点击移动的 WPF 游戏

    我试图将标签网格移动到鼠标的位置 就像冒险游戏中的移动一样 理想情况下 我会在途中删除并重新绘制它们 但是 现在我只想弄清楚如何将 int 转换为厚度或 pointtoscreen 到目前为止我有 player XMove int Mous
  • 如何仅更改 DateTime 的日期部分,同时保留时间部分?

    我在代码中使用了很多 DateTime 我想将这些日期时间更改为我的特定日期并保留 时间 1 2012 02 02 06 00 00 gt 2015 12 12 06 00 00 2 2013 02 02 12 00 00 gt 2015
  • 在 C# 中读取/写入命令行程序

    我正在尝试与 C 的命令行程序进行对话 它是一个情绪分析器 它的工作原理如下 CMD gt java jar analyser jar gt Starting analyser 这是我想从我的 C 程序插入内容的地方 例如 I love y
  • 最后从同一类中的其他构造函数调用构造函数

    我在这里读到可以调用另一个构造函数从同一类中的另一个构造函数调用构造函数 https stackoverflow com questions 829870 calling constructor from other constructor

随机推荐