我是实体框架的新手,我在Entity框架中阅读了一些关于不同上下文加载机制的文章。默认情况下启用延迟加载但是如果你的web和sql服务器之间存在高ping,那么你将使用Eager加载,而不是使用延迟加载1-by-1加载相关项目。但有一件事让我很困惑是明确加载。它通过禁用延迟加载来完成,但它本身甚至不是Eager loading ..我试图为我的研究做点什么....
private static void DifferentLoading()
{
//Lazy - by default
using (var ctx = new NorthwindDBContext())
{
var query = ctx.Categories.Take(3);
foreach (var category in query)
{
Console.WriteLine(category.CategoryName);
foreach (var product in category.Products)
{
Console.WriteLine(product.ProductName);
}
}
}
//Eager loading
using (var ctx = new NorthwindDBContext())
{
ctx.Configuration.LazyLoadingEnabled = false;
var query = ctx.Categories.Include("Products").Take(3); // .Include() to load forcefully
foreach (var category in query)
{
Console.WriteLine(category.CategoryName);
foreach (var product in category.Products)
{
Console.WriteLine(product.ProductName);
}
}
}
//Explicit loading -- On Demand load
using (var ctx = new NorthwindDBContext())
{
ctx.Configuration.LazyLoadingEnabled = false;
var query = ctx.Categories.Take(3);
foreach (var category in query)
{
Console.WriteLine(category.CategoryName);
ctx.Entry(category).Collection(c => c.Products).Load(); // .Include() to load explicitely
foreach (var product in category.Products)
{
Console.WriteLine(product.ProductName);
}
}
}
}
我发现针对不同场景触发了不同的sql
1)懒惰
SELECT TOP (3)
[c].[CategoryID] AS [CategoryID],
[c].[CategoryName] AS [CategoryName],
[c].[Description] AS [Description],
[c].[Picture] AS [Picture]
FROM [dbo].[Categories] AS [c]
GO
-- Region Parameters
DECLARE @EntityKeyValue1 Int = 1
-- EndRegion
SELECT
[Extent1].[ProductID] AS [ProductID],
[Extent1].[ProductName] AS [ProductName],
[Extent1].[SupplierID] AS [SupplierID],
[Extent1].[CategoryID] AS [CategoryID],
[Extent1].[QuantityPerUnit] AS [QuantityPerUnit],
[Extent1].[UnitPrice] AS [UnitPrice],
[Extent1].[UnitsInStock] AS [UnitsInStock],
[Extent1].[UnitsOnOrder] AS [UnitsOnOrder],
[Extent1].[ReorderLevel] AS [ReorderLevel],
[Extent1].[Discontinued] AS [Discontinued]
FROM [dbo].[Products] AS [Extent1]
WHERE [Extent1].[CategoryID] = @EntityKeyValue1
GO
-- Region Parameters
DECLARE @EntityKeyValue1 Int = 2
-- EndRegion
SELECT
[Extent1].[ProductID] AS [ProductID],
[Extent1].[ProductName] AS [ProductName],
[Extent1].[SupplierID] AS [SupplierID],
[Extent1].[CategoryID] AS [CategoryID],
[Extent1].[QuantityPerUnit] AS [QuantityPerUnit],
[Extent1].[UnitPrice] AS [UnitPrice],
[Extent1].[UnitsInStock] AS [UnitsInStock],
[Extent1].[UnitsOnOrder] AS [UnitsOnOrder],
[Extent1].[ReorderLevel] AS [ReorderLevel],
[Extent1].[Discontinued] AS [Discontinued]
FROM [dbo].[Products] AS [Extent1]
WHERE [Extent1].[CategoryID] = @EntityKeyValue1
GO
-- Region Parameters
DECLARE @EntityKeyValue1 Int = 3
-- EndRegion
SELECT
[Extent1].[ProductID] AS [ProductID],
[Extent1].[ProductName] AS [ProductName],
[Extent1].[SupplierID] AS [SupplierID],
[Extent1].[CategoryID] AS [CategoryID],
[Extent1].[QuantityPerUnit] AS [QuantityPerUnit],
[Extent1].[UnitPrice] AS [UnitPrice],
[Extent1].[UnitsInStock] AS [UnitsInStock],
[Extent1].[UnitsOnOrder] AS [UnitsOnOrder],
[Extent1].[ReorderLevel] AS [ReorderLevel],
[Extent1].[Discontinued] AS [Discontinued]
FROM [dbo].[Products] AS [Extent1]
WHERE [Extent1].[CategoryID] = @EntityKeyValue1
2)渴望
SELECT
[Project1].[CategoryID] AS [CategoryID],
[Project1].[CategoryName] AS [CategoryName],
[Project1].[Description] AS [Description],
[Project1].[Picture] AS [Picture],
[Project1].[C1] AS [C1],
[Project1].[ProductID] AS [ProductID],
[Project1].[ProductName] AS [ProductName],
[Project1].[SupplierID] AS [SupplierID],
[Project1].[CategoryID1] AS [CategoryID1],
[Project1].[QuantityPerUnit] AS [QuantityPerUnit],
[Project1].[UnitPrice] AS [UnitPrice],
[Project1].[UnitsInStock] AS [UnitsInStock],
[Project1].[UnitsOnOrder] AS [UnitsOnOrder],
[Project1].[ReorderLevel] AS [ReorderLevel],
[Project1].[Discontinued] AS [Discontinued]
FROM ( SELECT
[Limit1].[CategoryID] AS [CategoryID],
[Limit1].[CategoryName] AS [CategoryName],
[Limit1].[Description] AS [Description],
[Limit1].[Picture] AS [Picture],
[Extent2].[ProductID] AS [ProductID],
[Extent2].[ProductName] AS [ProductName],
[Extent2].[SupplierID] AS [SupplierID],
[Extent2].[CategoryID] AS [CategoryID1],
[Extent2].[QuantityPerUnit] AS [QuantityPerUnit],
[Extent2].[UnitPrice] AS [UnitPrice],
[Extent2].[UnitsInStock] AS [UnitsInStock],
[Extent2].[UnitsOnOrder] AS [UnitsOnOrder],
[Extent2].[ReorderLevel] AS [ReorderLevel],
[Extent2].[Discontinued] AS [Discontinued],
CASE WHEN ([Extent2].[ProductID] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
FROM (SELECT TOP (3) [c].[CategoryID] AS [CategoryID], [c].[CategoryName] AS [CategoryName], [c].[Description] AS [Description], [c].[Picture] AS [Picture]
FROM [dbo].[Categories] AS [c] ) AS [Limit1]
LEFT OUTER JOIN [dbo].[Products] AS [Extent2] ON [Limit1].[CategoryID] = [Extent2].[CategoryID]
) AS [Project1]
ORDER BY [Project1].[CategoryID] ASC, [Project1].[C1] ASC
3)显式
SELECT TOP (3)
[c].[CategoryID] AS [CategoryID],
[c].[CategoryName] AS [CategoryName],
[c].[Description] AS [Description],
[c].[Picture] AS [Picture]
FROM [dbo].[Categories] AS [c]
GO
-- Region Parameters
DECLARE @EntityKeyValue1 Int = 1
-- EndRegion
SELECT
[Extent1].[ProductID] AS [ProductID],
[Extent1].[ProductName] AS [ProductName],
[Extent1].[SupplierID] AS [SupplierID],
[Extent1].[CategoryID] AS [CategoryID],
[Extent1].[QuantityPerUnit] AS [QuantityPerUnit],
[Extent1].[UnitPrice] AS [UnitPrice],
[Extent1].[UnitsInStock] AS [UnitsInStock],
[Extent1].[UnitsOnOrder] AS [UnitsOnOrder],
[Extent1].[ReorderLevel] AS [ReorderLevel],
[Extent1].[Discontinued] AS [Discontinued]
FROM [dbo].[Products] AS [Extent1]
WHERE [Extent1].[CategoryID] = @EntityKeyValue1
GO
-- Region Parameters
DECLARE @EntityKeyValue1 Int = 2
-- EndRegion
SELECT
[Extent1].[ProductID] AS [ProductID],
[Extent1].[ProductName] AS [ProductName],
[Extent1].[SupplierID] AS [SupplierID],
[Extent1].[CategoryID] AS [CategoryID],
[Extent1].[QuantityPerUnit] AS [QuantityPerUnit],
[Extent1].[UnitPrice] AS [UnitPrice],
[Extent1].[UnitsInStock] AS [UnitsInStock],
[Extent1].[UnitsOnOrder] AS [UnitsOnOrder],
[Extent1].[ReorderLevel] AS [ReorderLevel],
[Extent1].[Discontinued] AS [Discontinued]
FROM [dbo].[Products] AS [Extent1]
WHERE [Extent1].[CategoryID] = @EntityKeyValue1
GO
-- Region Parameters
DECLARE @EntityKeyValue1 Int = 3
-- EndRegion
SELECT
[Extent1].[ProductID] AS [ProductID],
[Extent1].[ProductName] AS [ProductName],
[Extent1].[SupplierID] AS [SupplierID],
[Extent1].[CategoryID] AS [CategoryID],
[Extent1].[QuantityPerUnit] AS [QuantityPerUnit],
[Extent1].[UnitPrice] AS [UnitPrice],
[Extent1].[UnitsInStock] AS [UnitsInStock],
[Extent1].[UnitsOnOrder] AS [UnitsOnOrder],
[Extent1].[ReorderLevel] AS [ReorderLevel],
[Extent1].[Discontinued] AS [Discontinued]
FROM [dbo].[Products] AS [Extent1]
WHERE [Extent1].[CategoryID] = @EntityKeyValue1
我已经完成了这个帖子,它涵盖了我对急切加载和延迟加载的疑问。但显式加载仍然有点混乱
Eager , Lazy and explicit loading in EF6
上面的文章真的帮助我解决了我的问题
只有一个疑问......为什么我要明确地加载一些东西...我明确加载它然后使用它(明确)..更好我在需要它时加载它(懒惰)..到这一点有没有使用显式加载..何时在延迟加载时使用显式加载?任何帮助
现在我的问题是, 1)什么时候用?特别是我们真的需要明确加载吗?如果是,我们什么时候需要呢? 2)对我来说,为延迟加载和显式加载生成的查询几乎相似?懒惰和显式加载之间的实际区别是什么?