LINQ中的Include()有什么作用?


93

我尝试进行了大量研究,但我更像是数据库专家-因此,即使MSDN中的解释对我也没有任何意义。谁能解释一下,并提供一些示例Include()说明在SQL查询期间执行什么语句?


非常基础,我只知道一些聚合运算符的简单“选择”,“位置”,“排序”。我没有在LINQ中尝试加入,也没有包括在内。我的最终目标是能够将这些LINQ查询重写为SQL
CJ 2014年

Answers:


165

举例来说,假设您要获取所有客户的列表:

var customers = context.Customers.ToList();

并假定每个Customer对象都有对其的集合的引用Orders,并且每个对象都有对的引用,这些Order引用LineItems也可以引用a Product

如您所见,选择具有许多相关实体的顶级对象可能会导致查询需要从许多来源提取数据。作为一项性能指标,Include()您可以指示应该从数据库中读取哪些相关实体,作为同一查询的一部分。

使用相同的示例,这可能会带来所有相关的订单标题,但没有其他记录:

var customersWithOrderDetail = context.Customers.Include("Orders").ToList();

最后一点,因为您要求使用SQL,所以不带第一个语句Include()可能会生成一个简单的语句:

SELECT * FROM Customers;

最终调用的语句Include("Orders")可能如下所示:

SELECT *
FROM Customers JOIN Orders ON Customers.Id = Orders.CustomerId;

1
谢谢。使用你的榜样,我可以说,如果我想也包括LineItemsProducts,LINQ查询应该是这样的:var customersWithOrderDetail = context.Customers.Include("Orders").Include("LineItems").Include("Products").ToList();
CJ 2014年

2
是的,您可以链接多个调用以Include()沿不同的“路径”捕获对象。如果要使对象位于同一路径中,则只需进行一次调用即可指定整个路径。由于LineItems并且Products不共享任何路径组件,因此您确实需要单独的调用。
2014年

是否必须使用Include?我很确定我在解决方案上工作,无需使用它就可以获取相关对象。
2016年

@Jepzen取决于您是否使用延迟加载的实体。
Yuck

@Yuck,我相信这在使用延迟加载时有效,如果需要快速加载,则不需要使用“ include”语句,但这肯定会导致性能问题。请对此进行纠正。
萨姆

27

我只是想补充一点,“包含”是渴望加载的一部分。Microsoft在Entity Framework 6教程中对此进行了描述。这是链接:https : //docs.microsoft.com/zh-cn/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/reading-related-data-with-the asp-net-mvc应用程序中的实体框架


摘录自链接页面:

实体框架可以通过以下几种方式将相关数据加载到实体的导航属性中:

延迟加载。首次读取实体时,不会检索相关数据。但是,第一次尝试访问导航属性时,将自动检索该导航属性所需的数据。这导致将多个查询发送到数据库-一个查询实体本身,而每次必须检索该实体的相关数据时。DbContext类默认情况下启用延迟加载。

渴望加载。读取实体时,将同时检索相关数据。通常,这会导致单个联接查询,该查询检索所需的所有数据。您可以使用Include方法指定紧急加载。

显式加载。这类似于延迟加载,不同之处在于您可以通过代码显式检索相关数据。访问导航属性时,它不会自动发生。您可以通过获取实体的对象状态管理器条目并为集合调用Collection.Load方法或为拥有单个实体的属性调用Reference.Load方法来手动加载相关数据。(在下面的示例中,如果要加载Administrator导航属性,请替换Collection(x => x.Courses)Reference(x => x.Administrator)。)通常,只有在关闭惰性加载后,才使用显式加载。

由于它们不会立即检索属性值,因此延迟加载和显式加载也都称为延迟加载。


3
欢迎来到SO =)只是一个建议,但是当您回答这样的问题时,请尽可能提供一个代码段。链接可能会失效。
The_Cthulhu_Kid

2

可以将其视为在子项目原本是延迟加载的情况下强制执行Eager-Loading。

首先,查询EF发送到数据库将产生较大的结果,但是在访问所包含的项目时,将不会进行后续查询。

另一方面,如果没有它,当您第一次访问子项目时,EF将在以后执行separte查询。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.