Linq-to-SQL метод расширения include не работает - PullRequest
0 голосов
/ 31 января 2012

Я пытался 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();

и контекст данных имеет опцию загрузки LoadWith(x => x.ItemImages).

, которая производит этот оператор 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-запрос, но, по крайней мере, с одним количеством запросов данных один запросработает быстрее, сo было бы довольно интересно увидеть решение.

1 Ответ

1 голос
/ 01 февраля 2012

Метод включения в моем блоге был продемонстрирован и протестирован только с отношением «один к одному».

Проецируя запрос, который ссылается на один, он заполняет кэш идентификаторов LINQ to 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...