C# 包含的实体框架性能问题
我想知道哪一个性能更好C# 包含的实体框架性能问题,c#,entity-framework,C#,Entity Framework,我想知道哪一个性能更好 var allocations = Catalog.ResourceAllocations .Where(c => c.Pet.Key == petKey && c.Pet.Owner.Key == ownerKey) .Include(k => k.Appointment) .Include(k => k.Service)
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();
以下状态的文档(请阅读结尾处的注释-它描述了包括路径的工作方式):
路径包罗万象。例如,如果包含调用指示
包括(“订单.订单行”),不仅包括订单行,
而且还有订单
所以k.Appointment.Provider.Address
将包括k.Appointment
。即使没有性能影响,第二个查询也会更好,因为它不包含重复的包含定义
更新:在数据库查询中不会有性能差异,因为两个LINQ查询将生成相同的SQL查询(嗯,左外联接的顺序可能不同)。但是在查询生成上会有很小的性能差异,因为当您包含一些路径时,将生成新的ObjectQuery
(是的,每个Include
都会创建新的查询,而不是修改现有的查询)
注意:知道为什么没有区别很有意思-我对Entity Framework 6源代码进行了一些调查,发现了EF收集应该包含的路径的方式。有一个内部密封类Span
,它保存路径集合,以确定查询中包含哪些元素<代码>span路径非常简单-它只是字符串列表上的一个包装器,表示要包含的导航:
internal class SpanPath
{
// you can think naviagations as path splitted by dots
public readonly List<string> Navigations;
// ...
}
因此,以下是发生的情况-当您包括新路径时,然后:
Appointment.Provider.Address
路径时,第3步将删除Appointment
路径,因为它是Appointment.Provider.Address
的子路径
摘要:
不要在查询中显式包含子路径-这将导致新的ObjectQuery实例创建,并且不会影响生成的查询。它将被忽略,或者在您添加包含此路径的路径时将被删除。有关以下状态的文档(请阅读结尾处的注释-它描述了路径包含的工作原理):
路径包罗万象。例如,如果包含调用指示
包括(“订单.订单行”),不仅包括订单行,
而且还有订单
所以k.Appointment.Provider.Address
将包括k.Appointment
。即使没有性能影响,第二个查询也会更好,因为它不包含重复的包含定义
更新:在数据库查询中不会有性能差异,因为两个LINQ查询将生成相同的SQL查询(嗯,左外联接的顺序可能不同)。但是在查询生成上会有很小的性能差异,因为当您包含一些路径时,将生成新的ObjectQuery
(是的,每个Include
都会创建新的查询,而不是修改现有的查询)
注意:知道为什么没有区别很有意思-我对Entity Framework 6源代码进行了一些调查,发现了EF收集应该包含的路径的方式。有一个内部密封类Span
,它保存路径集合,以确定查询中包含哪些元素<代码>span路径非常简单-它只是字符串列表上的一个包装器,表示要包含的导航:
internal class SpanPath
{
// you can think naviagations as path splitted by dots
public readonly List<string> Navigations;
// ...
}
因此,以下是发生的情况-当您包括新路径时,然后:
Appointment.Provider.Address
路径时,第3步将删除Appointment
路径,因为它是Appointment.Provider.Address
的子路径
摘要:
不要在查询中显式包含子路径-这将导致新的ObjectQuery实例创建,并且不会影响生成的查询。它将被忽略,或者在您添加包含此路径的路径时将被删除。您是否尝试运行两个查询?@SergeyBerezovskiy是的。Out put是相同的。您是否尝试运行两个查询?@SergeyBerezovskiy是的。Out put是相同的。@Sampath欢迎:)我做了一些调查并发布了结果。我想你会感兴趣的。真的很有趣。谢谢你。但是你能告诉我,你有没有使用任何工具来调查“SpanPath”等。关于EF的详细信息?@Sampath上有EF的来源,但你总是可以使用像Reflector这样的工具来调查组件。非常感谢Sergey。我会检查一下。:)@Sampath欢迎:)我做了一点调查,并公布了结果。我想你会感兴趣的。真的很有趣。谢谢你。但是你能告诉我,你有没有使用任何工具来调查“SpanPath”等。关于EF的详细信息?@Sampath上有EF的来源,但你总是可以使用像Reflector这样的工具来调查组件。非常感谢Sergey。我会检查一下。:)