繁体   English   中英

LINQ执行多个查询而不是单个“加入”查询

[英]LINQ performing multiple queries instead of a single “joined” query

无论如何我不是LINQ高级用户,但可以在基本级别上摸索。 我有一个关于LINQ如何制定它的查询“策略”的问题。 我将尝试尽可能地解释这一点,并通过记忆写出一个非常愚蠢的例子。

我有一个包含多个数据库视图的数据模型。 假设视图的列结构如下:

PersonView

PersonViewId | Surname | GivenName | OtherViewId
------------------------------------------------

其他视图

OtherViewId | PersonViewId | Name
---------------------------------

在设置视图的主键(PersonView.PersonViewId / OtherView.OtherViewId)并将相应的字段设置为非nulable之后,我在PersonView.PersonViewId(Parent)与OtherView.PersonViewId(Child)之间创建了一个关联。 我将它设置为“一对一”并编写一些代码来使用它:

StringBuilder s = new StringBuilder();
foreach(PersonView p in dc.PersonViews)
{
    s.AppendLine(p.OtherViews.Name + "<br />");
}

在注意到性能极差之后,我对数据库进行了分析,发现它正在对foreach语句中的每个PersonView进行查询。

此时,我重新编写了查询,并在DBML中将关联替换为LINQ查询中的JOIN,对数据库进行了分析,并按预期查询了数据库,仅查询一次。

我认为这与某些事情有关,然后实际上正在查询数据库,但我不确定在哪里进行调试。 有人能指出我正确的方向,以帮助我提高使用协会的表现,还是我坚持使用JOIN来完成我需要的东西?

谢谢 :)

这是由延迟加载引起的 - 你可以通过应用LoadWith() (相当于Linq到SQL的EF的Include() )然后再进行查询来解决这个问题:

var dlo = new DataLoadOptions();
dlo.LoadWith<PersonView>(p => p.OtherViews);
dc.LoadOptions = dlo;
//your query here

这是LINQ-2-SQL的延迟加载(也称为延迟加载)功能,当你执行p.OtherViews.Name它正在对OtherViews表进行查询。

有几种方法可以解决它,一种是关闭延迟加载:

dc.DeferredLoadingEnabled = false;

另一种方法是在结果中投射您想要的所有内容,并使用投影:

var people = from p in dc.PersonViews
             select new {
                 Person = p,
                 Name = p.OtherViews.Name
             };

然后是BrokenGlass的建议,直到现在我都不知道:-)

你看到这个的原因是Linq对这些关系使用延迟加载。 换句话说,在您真正尝试使用它之前,Linq不会加载关联。

这可以帮助提高性能,因为如果您不总是需要关联,则不会执行不必​​要的JOIN,也不会检索不需要的数据。

如果您确定需要数据,它会影响性能,并且它会继续发出请求。

您可以通过保持关联原样来解决这个问题,但请使用DataLoadOptions。 例如:

var dc = new DataContext();
dc.DeferredLoadingEnabled = false;

DataLoadOptions loadOptions = new DataLoadOptions();
loadOptions.LoadWith<PersonView>(o => o.OtherView);

dc.LoadOptions = loadoptions;

现在,无论何时查询PersonView,它都会自动加载OtherView关系。

这种方法的好处是你可以在需要时打开和关闭它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM