[英]Entity Framework Performance issue with Include
我想知道哪个表现更好 ?
var allocations =
Catalog.ResourceAllocations
.Where(c => c.Pet.Key == petKey && c.Pet.Owner.Key == ownerKey)
.Include(k => k.Appointment)
.Include(k => k.Service)
.Include(k => k.Appointment.Provider.Address)
.ToList();
要么
var allocations =
Catalog.ResourceAllocations
.Where(c => c.Pet.Key == petKey && c.Pet.Owner.Key == ownerKey)
.Include(k => k.Appointment.Provider.Address)
.Include(k => k.Service)
.ToList();
DbQuery<T>.Include(path)
文档指出(请最后阅读注释 -它描述了包括路径的工作方式):
路径是包罗万象的。 例如,如果一个include调用指示Include(“ Orders.OrderLines”),则不仅将包括OrderLines,还将包括Orders。
因此, k.Appointment.Provider.Address
仍将包括k.Appointment
。 即使不影响性能,第二个查询还是更好的,因为它不包含重复的包含定义。
更新:数据库查询不会有性能差异,因为两个LINQ查询都将导致生成相同的SQL查询(嗯,左外部连接的顺序可能会有所不同)。 但是查询生成的性能会有细微的差别,因为当包含一些路径时,将生成新的ObjectQuery
(是的,每个Include
都会创建新查询而不是修改现有查询)。
注意:知道为什么没有区别很有趣-我对Entity Framework 6来源进行了一些调查,发现了EF如何收集应包括的路径。 内部有一个内部密封类Span
,该类保存路径集合,以确定哪些元素包含在查询中。 SpanPath
非常简单-只是字符串列表的包装,代表要包含的导航:
internal class SpanPath
{
// you can think naviagations as path splitted by dots
public readonly List<string> Navigations;
// ...
}
Span
是一个包含所有包含路径的类:
internal sealed class Span
{
private readonly List<SpanPath> _spanList = new List<SpanPath>();
public void Include(string path)
{
Check.NotEmpty(path, "path");
SpanPath spanPath = new SpanPath(ParsePath(path));
this.AddSpanPath(spanPath);
}
internal void AddSpanPath(SpanPath spanPath)
{
if (this.ValidateSpanPath(spanPath))
{
this.RemoveExistingSubPaths(spanPath);
this._spanList.Add(spanPath);
}
}
private bool ValidateSpanPath(SpanPath spanPath)
{
for (int i = 0; i < this._spanList.Count; i++)
{
if (spanPath.IsSubPath(this._spanList[i]))
return false;
}
return true;
}
}
所以,这就是发生的情况-当您包含新路径时,则:
如果在第一种情况下包括Appointment.Provider.Address
路径,则Appointment
路径将在步骤3中删除,因为它是Appointment.Provider.Address
子路径。
摘要 :
不要在查询中明确包含子路径-这会导致创建新的ObjectQuery实例,并且不会影响生成的查询。 当添加包含此路径的路径时,它会被忽略,或者会被删除。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.