16

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

            Parent
    Child1          Child2
Grandchild1

Parent > Child1是一对多的关系

Child1 > Grandchild1是一对 n 关系(其中 n 为零到无穷大)

Parent > Child2是一对 n 关系(其中 n 为零到无穷大)

我能够急切地加载 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<Child1> 的原因是为了水合业务对象。

我的想法是:

  1. 以错误的方式处理这个问题。
  2. 可以选择调用存储过程吗?
  3. 我的组织不应该使用 LINQ to SQL 作为 ORM?

任何帮助是极大的赞赏。

谢谢,

-斯科特

4

2 回答 2

14

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

于 2010-03-30T15:17:19.330 回答
0
var children2 = from child2 in dataContext.Child2
                where children.Any(c1 => c1.Parent == child2.Parent)
                select child2;

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

于 2010-03-30T20:21:45.030 回答