2

为了减少到数据库的往返,我希望为父对象“预加载”子集合。我希望如果我将构成子集合的对象加载到 DataContext 缓存中,Linq2SQL 将使用这些对象而不是进入数据库。

例如,假设我有一个带有两个子集合的 Person 对象:Children 和 Cars。

我认为这可能有效:

var children = from p in dbc.Person
               select p.Children;

var cars = from p in dbc.Person
           select p.Cars;

var people = from p in dbc.Person
             select p;


var dummy1 = children.ToList();
var dummy2 = cars.ToList();

foreach(var person in people){
    Debug.WriteLine(person.Children.Count);
}

但相反,每次调用 时,我仍然会访问一次数据库person.Children.Count,即使所有子项都已加载到 DataContext 中。

最终,我正在寻找一种在尽可能少的数据库访问中加载完整对象图(具有多个子集合)的方法。

我知道DataLoadOptions类(和LoadWith),但它仅限于一个子集合,这对我来说是个问题。

如果我仍然能够构建完整的对象图(当然还有一个 Linq2SQL 对象),而无需对对象进行大量额外操作,我不介意使用存储过程。

4

1 回答 1

0

我不认为您需要的内容可以直接使用 LINQ-SQL 甚至 SQL 以您期望的方式实现。

当您考虑 SQL 的工作原理时,单个一对多关系可以很容易地通过内部/左连接来展平。在此之后,如果您想要另一组对象,理论上您可以编写另一个左连接,它将带回另一个表中的所有行。但是想象一下 SQL 将提供的输出,它不容易返回到对象图中。ORM 通常会开始按行查询以提供此数据。这方面的一个例子是DataLoadOptions使用 LINQ-SQL 编写多个级别,您将开始看到这一点。

此外,许多 LEFT JOIN 对性能的影响很容易超过单次查询的好处。

考虑你的例子。您正在从这两个表中取回所有行。这进一步带来了两个问题:

  • 这些表中的数据可能比您预期的要多得多。一次全部拉回 SQL 中的 1000 行可能不利于性能。然后,您期望 LINQ-SQL 在列表中搜索匹配的对象。根据使用情况,我想 SQL 可以更快地提供这些数据。

  • 您期望的行为是隐藏的,对我来说,在大表上运行 SELECT 可能会通过缓存所有行来增加应用程序的内存使用量,这是不寻常的。也许他们可以将其作为一个选项包含在内,或者提供您自己的扩展方法。

解决方案

我个人会开始考虑在 LINQ-SQL 之外缓存数据,然后从 ASP.Net / Memory Cache / Your Cache provider 检索对象,如果认为创建完整对象图的成本很高的话。

DataLoadOptions依靠内置实体关系+一些手动缓存的一级加号可能会省去很多麻烦。

我遇到过这个特殊问题几次,还没有想到其他任何事情。

于 2013-04-10T18:40:40.993 回答