如何使用LINQ to SQL加载兄弟数据?

时间:2010-03-30 15:01:32

标签: linq linq-to-sql eager-loading

目标是使用LINQ to SQL向SQL Server发出最少的查询,而不使用匿名类型。该方法的返回类型需要是IList< Child1>。关系如下:

            Parent
    Child1          Child2
Grandchild1

父母> Child1 是一对多的关系

Child1>孙子1 是一对一关系(其中n为0到无穷大)

父母> Child2 是一对一的关系(其中n为0到无穷大)

我能够急切加载Parent,Child1和Grandchild1数据,从而导致向SQL Server发出一个查询。

带有加载选项的查询急切加载除兄弟数据(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查询并将结果集合并在一起(不太漂亮),但是在访问兄弟数据时它仍然是延迟加载的。

添加兄弟加载选项将为每个Grandchild1和Child2记录向SQL Server发出查询(这正是我想要避免的):

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查询以加入所有数据,希望它能够加载数据,但是当访问Child2或Grandchild1的LINQ to SQL EntitySet时,它会延迟加载数据。

返回IList&lt; Child1&gt;的原因是为了保护商业对象。

我的想法是我要么:

  1. 以错误的方式解决这个问题。
  2. 可以选择调用存储过程吗?
  3. 我的组织不应该将LINQ to SQL用作ORM?
  4. 非常感谢任何帮助。

    谢谢,

    -Scott

2 个答案:

答案 0 :(得分:14)

您拥有的内容应该是正确的,除了您已经设置的LoadOptions之外,还需要添加此dataContext.DeferredLoadingEnabled = false;

答案 1 :(得分:0)

var children2 = from child2 in dataContext.Child2
                where children.Any(c1 => c1.Parent == child2.Parent)
                select child2;

应该导致单个存在的查询,因此它最终将成为两个查询。