Как стремиться загрузить данные родного брата, используя LINQ to SQL? - PullRequest
16 голосов
/ 30 марта 2010

Цель состоит в том, чтобы выдать наименьшее количество запросов к SQL Server с использованием LINQ to SQL без использования анонимных типов. Тип возвращаемого значения для метода должен быть IList . Отношения таковы:

            Parent
    Child1          Child2
Grandchild1

Родитель> Ребенок1 - это отношение один-ко-многим

Child1> Grandchild1 является отношением один-к-n (где n - от нуля до бесконечности)

Parent> Child2 - это отношение один к n (где n - от нуля до бесконечности)

Я могу загружать данные Parent, Child1 и Grandchild1, что приводит к одному запросу на SQL Server.

Этот запрос с опциями загрузки eager загружает все данные, кроме данных одного уровня (Child2):

DataLoadOptions loadOptions = new DataLoadOptions();
loadOptions.LoadWith<Child1>(o => o.GrandChild1List);
loadOptions.LoadWith<Child1>(o => o.Parent);

dataContext.LoadOptions = loadOptions;

IQueryable<Child1> children = from child in dataContext.Child1
                                select child;

Мне нужно также загрузить данные родного брата. Один из подходов, которые я попробовал, - это разделение запроса на два запроса LINQ to SQL и объединение наборов результатов вместе (не очень), однако при доступе к одноуровневым данным он в любом случае загружается лениво.

При добавлении параметра загрузки «брат-сестра» будет выдан запрос к SQL Server для каждой записи Grandchild1 и Child2 (именно этого я и пытаюсь избежать):

DataLoadOptions loadOptions = new DataLoadOptions();
loadOptions.LoadWith<Child1>(o => o.GrandChild1List);
loadOptions.LoadWith<Child1>(o => o.Parent);
loadOptions.LoadWith<Parent>(o => o.Child2List);

dataContext.LoadOptions = loadOptions;

IQueryable<Child1> children = from child in dataContext.Child1
                                select child;


exec sp_executesql N'SELECT * FROM [dbo].[Child2] AS [t0]
WHERE [t0].[ForeignKeyToParent] = @p0',N'@p0 int',@p0=1

exec sp_executesql N'SELECT * FROM [dbo].[Child2] AS [t0]
WHERE [t0].[ForeignKeyToParent] = @p0',N'@p0 int',@p0=2

exec sp_executesql N'SELECT * FROM [dbo].[Child2] AS [t0]
WHERE [t0].[ForeignKeyToParent] = @p0',N'@p0 int',@p0=3

exec sp_executesql N'SELECT * FROM [dbo].[Child2] AS [t0]
WHERE [t0].[ForeignKeyToParent] = @p0',N'@p0 int',@p0=4

Я также написал запросы LINQ to SQL для объединения всех данных в надежде на то, что он будет стремиться загрузить данные, однако, когда к LINQ to SQL EntitySet для Child2 или Grandchild1 обращаются, он лениво загружает данные.

Причина возврата IList заключается в увлажнении бизнес-объектов.

Я думаю, что я тоже:

  1. Неправильный подход к этой проблеме.
  2. Есть возможность вызова хранимой процедуры?
  3. Моя организация не должна использовать LINQ to SQL в качестве ORM?

Любая помощь очень ценится.

Спасибо,

-Скотт

Ответы [ 2 ]

14 голосов
/ 30 марта 2010

То, что у вас должно быть правильно, вам нужно добавить это dataContext.DeferredLoadingEnabled = false; в дополнение к уже установленным параметрам загрузки.

0 голосов
/ 31 марта 2010
var children2 = from child2 in dataContext.Child2
                where children.Any(c1 => c1.Parent == child2.Parent)
                select child2;

Должен привести к одному существующему запросу, поэтому в итоге получится два запроса.

...