Linq to sql 使用DataContext缓存预加载子集合

Linq to sql 使用DataContext缓存预加载子集合,linq-to-sql,Linq To Sql,为了减少往返数据库的次数,我希望为父对象“预加载”子集合。我的希望是,如果我将组成子集合的对象加载到DataContext缓存中,Linq2SQL将使用这些对象,而不是访问数据库 例如,假设我有一个Person对象,它有两个子集合:Children和Cars 我想这可能有用: var children = from p in dbc.Person select p.Children; var cars = from p in dbc.Person

为了减少往返数据库的次数,我希望为父对象“预加载”子集合。我的希望是,如果我将组成子集合的对象加载到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);
}
但是,尽管所有的子项都已加载到DataContext中,但每次调用
person.Children.Count
,我仍然会访问数据库一次

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

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


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

我认为,使用LINQ-SQL,甚至按照您期望的方式使用SQL,您所需要的都是不可能的

当你考虑SQL是如何工作的时候,一个单一的关系可以很容易地被一个内/左连接压扁。在此之后,如果需要另一组对象(包括),理论上可以编写另一个左联接,它将返回另一个表中的所有行。但是想象一下SQL将提供的输出,它不容易返回到对象图中。ORM通常会开始查询每行以提供此数据。例如,使用LINQ-SQL编写多级

DataLoadOptions
,您将开始看到这一点

此外,许多左连接对性能的影响很容易超过单个查询的感知好处

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

  • 这些表中的数据可能比您预期的多得多。一次收回SQL中的1000行可能不利于性能。然后,您希望LINQ-SQL在列表中搜索匹配的对象。依赖于使用,我认为SQL可以更快地提供这些数据

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

解决方案

我个人会开始考虑在LINQ-SQL之外缓存数据,然后从ASP.Net/内存缓存/您的缓存提供程序中检索对象,如果认为创建完整对象图的成本很高的话

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


我已经遇到过这个问题好几次了,还没有想到其他任何事情。

您是否考虑过
Include
并禁用代理创建/延迟加载?我在L2S中没有找到任何对“Include”的引用…这不是EF功能吗?我看到DamienG(微软L2S和EF开发人员之一)发表了这篇文章(),但这不适用于一对多关系。我从您使用的
DataContext
假设您使用的是实体框架。您正在使用什么类型的ORM?您使用的是什么类型的连接器?你能把这个问题定义得更清楚一点吗?@TravisJ:他在问题的第一段提到他正在使用linqtosql@内森:为什么你认为
LoadWith
只限于一个子集合?您可以简单地使用多个
LoadWith
调用来加载多个子集合。不要忘记将
delferredLoadingEnabled
设置为false。