我想知道哪个性能更好?
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();
答案 0 :(得分:4)
DbQuery<T>.Include(path)
州的文档(最后请阅读 NOTES - 介绍路径如何工作):
路径包罗万象。例如,如果包含呼叫指示 包含(“Orders.OrderLines”),不仅包括OrderLines, 还有订单。
所以k.Appointment.Provider.Address
无论如何都会包含k.Appointment
。即使没有性能损失,第二个查询也更好,因为它不包含重复的包含定义。
更新:数据库查询中没有性能差异,因为两个LINQ查询都会生成相同的SQL查询(嗯,LEFT OUTER JOINS的顺序可能不同)。但是在查询生成方面会有很小的性能差异,因为当你包含一些路径时,会生成新的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
路径,则会在步骤3中删除Appointment
路径,因为它是Appointment.Provider.Address
的子路径。
摘要:
不要在查询中明确包含子路径 - 它将导致新的ObjectQuery实例创建,并且它不会影响生成的查询。它将被忽略,或者在您添加包含此路径的路径时将被删除。