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查询更快,但至少就我的数据量而言,单个查询的工作速度更快,所以看到一个解决方案会很有趣。

Linq-to-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的项目。