Linq-to-SQL包含扩展方法不起作用
本文关键字:不起作用 方法 扩展 包含 Linq-to-SQL | 更新日期: 2023-09-27 18:22:11
我正在尝试来自的Include
扩展方法http://damieng.com/blog/2010/05/21/include-for-linq-to-sql-and-maybe-other-providers,但它并没有真正起作用。
所以我在Linq-to-SQL:中有这个查询
var items = dataContext.Items()
.Where(x => x.Id < 100)
.ToList();
并且数据上下文具有加载选项CCD_ 2。
生成以下SQL语句:
SELECT [t0].[Id], [t0].[Number], [t0].[Title], [t1].[Id] AS [Id2], [t1].[ItemId], [t1].[Url], (
SELECT COUNT(*)
FROM [dbo].[ItemImage] AS [t2]
WHERE [t2].[ItemId] = [t0].[Id]
) AS [value]
FROM [dbo].[Item] AS [t0]
LEFT OUTER JOIN [dbo].[ItemImage] AS [t1] ON [t1].[ItemId] = [t0].[Id]
WHERE [t0].[Id] < @p0
ORDER BY [t0].[Id], [t1].[Id]
现在,如果我不使用数据加载选项,而是将查询重写为:
var items = dataContext.Items()
.Where(x => x.Id < 100)
.Select(x=>new Tuple<Item, EntitySet<ItemImage>>(x, x.ItemImages))
.AsEnumerable()
.Select(x=>x.Item1)
.ToList();
生成的SQL语句是相同的:
SELECT [t0].[Id], [t0].[Number], [t0].[Title], [t1].[Id] AS [Id2], [t1].[ItemId], [t1].[Url], (
SELECT COUNT(*)
FROM [dbo].[ItemImage] AS [t2]
WHERE [t2].[ItemId] = [t0].[Id]
) AS [value]
FROM [dbo].[Item] AS [t0]
LEFT OUTER JOIN [dbo].[ItemImage] AS [t1] ON [t1].[ItemId] = [t0].[Id]
WHERE [t0].[Id] < @p0
ORDER BY [t0].[Id], [t1].[Id]
但是,如果我正在访问items[0].ItemImages
属性,它确实会请求SQL Server检索项映像,所以看起来它已经拥有了避免额外查询所需的所有数据,但物化出现了问题,它仍然会进行额外的查询,尽管它可以避免这些查询。
我可以设法解决这个问题吗?
更新:我对使用LoadWith选项的性能持怀疑态度,并认为在代码中执行两个查询(一个用于项,第二个用于图像)和映射会比Linq2Sql生成的单个SQL查询更快,但至少就我的数据量而言,单个查询的工作速度更快,所以看到一个解决方案会很有趣。
我博客上的include方法只通过一对一关系进行了演示和测试。
通过将引用的查询投影到查询,它将填充LINQ到SQL标识缓存。当以后导航任何导航属性时,它将首先到达该缓存。
不幸的是,LINQ to SQL不够高级,无法以这种方式缓存到许多关联。
您可以选择使用LoadWith,也可以编写一个按项目和分组的查询,例如
var items = dataContext.ItemImages()
.Where(x => x.Item.Id < 100)
.Select(x => new Tuple<ItemImage, Item>(x, x.Item))
.AsEnumerable()
.Select(x = > x.Item1)
.GroupBy(x => x.Item);
这个查询需要注意的是,您不会看到任何没有ItemImages的项目。