为了减少到数据库的往返,我希望为父对象“预加载”子集合。我希望如果我将构成子集合的对象加载到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对象)而不需要对对象进行大量额外操作,我不介意使用存储过程。
答案 0 :(得分:0)
我不认为你需要的是LINQ-SQL,甚至是你期望的SQL。
当您考虑SQL如何工作时,内部/左侧连接可以轻松地平滑单个一对多关系。在此之后,如果你想要另一组对象,理论上你可以写另一个左连接,它会带回另一个表中的所有行。但是想象一下SQL提供的输出,它不容易回到对象图中。 ORM通常会开始每行查询以提供此数据。一个例子是使用LINQ-SQL编写多个级别DataLoadOptions
,您将开始看到这一点。
此外,许多LEFT JOIN对性能的影响很容易超过单个查询的预期效益。
考虑你的例子。您正从这两个表中提取 ALL 行。这带来了两个问题:
表中可能会获得比预期更多的数据。一次性回退SQL中的1000行可能不利于性能。然后,您希望LINQ-SQL在列表中搜索匹配的对象。根据使用情况,我想SQL可以更快地提供这些数据。
您期望的行为是隐藏的,对我而言,在大型表上运行SELECT可能会通过缓存所有行来扩大应用程序的内存使用量,这是不寻常的。也许他们可以将其作为选项包含或提供您自己的扩展方法。
<强>解决方案强>
我个人会开始考虑在LINQ-SQL之外缓存数据,然后从ASP.Net / Memory Cache / Your Cache提供程序中检索对象,如果认为完整对象图的创建成本很高。
DataLoadOptions
的一个级别加上依赖内置的实体关系+一些手动缓存可能会让人头疼不已。
我已经遇到过几次这个特殊问题而且还没有想过其他任何问题。