我试着做了很多研究,但我更喜欢数据库a-所以即使MSDN上的解释对我来说也没有任何意义。有人能解释一下,并提供一些例子来说明Include()语句在SQL查询中的作用吗?
Include()
SQL
jhkqcmku1#
例如,假设您希望获得所有客户的列表:
var customers = context.Customers.ToList();
让我们假设每个Customer对象都有一个对它的Orders集合的引用,并且每个Order都有对LineItems的引用,LineItems也可能引用Product。正如您所看到的,选择具有许多相关实体的顶级对象可能会导致需要从许多源中提取数据的查询。作为一种性能度量,Include()允许您指示应从数据库中读取哪些相关实体作为同一查询的一部分。使用相同的示例,这可能会引入所有相关的订单题头,但不引入任何其他记录:
Customer
Orders
Order
LineItems
Product
var customersWithOrderDetail = context.Customers.Include("Orders").ToList();
最后一点,因为您要求使用SQL,第一个没有Include()的语句可以生成一个简单的语句:
SELECT * FROM Customers;
调用Include("Orders")的最后一条语句可能如下所示:
Include("Orders")
SELECT * FROM Customers JOIN Orders ON Customers.Id = Orders.CustomerId;
ngynwnxp2#
我只是想补充一下,“Include”是急切加载的一部分。它在微软的Entity Framework 6教程中有描述。下面是链接:https://learn.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/reading-related-data-with-the-entity-framework-in-an-asp-net-mvc-application链接页面摘录:以下是实体框架将相关数据加载到实体的导航属性中的几种方法:
**延迟加载。**第一次读取实体时,不会检索相关数据。但是,第一次尝试访问导航属性时,会自动检索该导航属性所需的数据。这会导致向数据库发送多个查询-一个针对实体本身,每次必须检索实体的相关数据时都发送一个。DbContext类默认启用延迟加载。**立即载入。读取实体时,会沿着撷取相关数据。这通常会产生撷取所有所需数据的单一链接查询。您可以使用Include**方法来指定立即载入。**显式加载。**这类似于惰性加载,不同之处在于您在代码中显式检索相关数据;通过获取实体的对象状态管理器条目并调用Collection.Load方法(对于集合)或Reference.Load方法(对于包含单个实体的属性)来手动加载相关数据。(在以下示例中,如果要加载“管理员”导航属性,通常只有在关闭惰性加载时才使用显式加载。
Include
因为延迟加载和显式加载不会立即检索属性值,所以它们也都称为延迟加载。
ltqd579y3#
您可以将其视为在子项延迟加载的情况下强制执行Eager-Loading。发送到数据库的查询EF最初将产生较大的结果,但在访问包含的项目时,将不会进行后续查询。另一方面,如果没有它,EF将在您第一次访问子项时执行单独的查询。
k4emjkb14#
include()方法只是为了包含相关的实体。但是在sql上发生的事情是基于那些实体之间的关系的,你要包含你要获取的数据。您的LINQ查询决定必须使用什么类型的连接,可能有左外连接,可能有内连接,可能有右连接等...@Corey Adler
4条答案
按热度按时间jhkqcmku1#
例如,假设您希望获得所有客户的列表:
让我们假设每个
Customer
对象都有一个对它的Orders
集合的引用,并且每个Order
都有对LineItems
的引用,LineItems
也可能引用Product
。正如您所看到的,选择具有许多相关实体的顶级对象可能会导致需要从许多源中提取数据的查询。作为一种性能度量,
Include()
允许您指示应从数据库中读取哪些相关实体作为同一查询的一部分。使用相同的示例,这可能会引入所有相关的订单题头,但不引入任何其他记录:
最后一点,因为您要求使用SQL,第一个没有
Include()
的语句可以生成一个简单的语句:调用
Include("Orders")
的最后一条语句可能如下所示:ngynwnxp2#
我只是想补充一下,“Include”是急切加载的一部分。它在微软的Entity Framework 6教程中有描述。下面是链接:https://learn.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/reading-related-data-with-the-entity-framework-in-an-asp-net-mvc-application
链接页面摘录:
以下是实体框架将相关数据加载到实体的导航属性中的几种方法:
**延迟加载。**第一次读取实体时,不会检索相关数据。但是,第一次尝试访问导航属性时,会自动检索该导航属性所需的数据。这会导致向数据库发送多个查询-一个针对实体本身,每次必须检索实体的相关数据时都发送一个。DbContext类默认启用延迟加载。
**立即载入。读取实体时,会沿着撷取相关数据。这通常会产生撷取所有所需数据的单一链接查询。您可以使用
Include
**方法来指定立即载入。**显式加载。**这类似于惰性加载,不同之处在于您在代码中显式检索相关数据;通过获取实体的对象状态管理器条目并调用Collection.Load方法(对于集合)或Reference.Load方法(对于包含单个实体的属性)来手动加载相关数据。(在以下示例中,如果要加载“管理员”导航属性,通常只有在关闭惰性加载时才使用显式加载。
因为延迟加载和显式加载不会立即检索属性值,所以它们也都称为延迟加载。
ltqd579y3#
您可以将其视为在子项延迟加载的情况下强制执行Eager-Loading。
发送到数据库的查询EF最初将产生较大的结果,但在访问包含的项目时,将不会进行后续查询。
另一方面,如果没有它,EF将在您第一次访问子项时执行单独的查询。
k4emjkb14#
include()方法只是为了包含相关的实体。但是在sql上发生的事情是基于那些实体之间的关系的,你要包含你要获取的数据。
您的LINQ查询决定必须使用什么类型的连接,可能有左外连接,可能有内连接,可能有右连接等...@Corey Adler