在实体框架中投射懒惰,渴望还是明确?

时间:2011-04-15 01:42:17

标签: entity-framework linq-to-entities entity

我已经了解了延迟加载,使用.include进行急切加载以及使用.load()进行显式加载,但令我困惑的是当你在查询中投影并明确请求这样的导航属性时:

var address = from a in context.Addresses
              select {a, Name = a.Contact.Name}

此处Contact是地址中的导航属性,链接到Contact实体。

我试着打开和关闭延迟加载,它可以双向工作。我想知道我何时请求这样的数据,我是否急于加载或延迟加载?我的理解是只对数据库进行一次查询,这意味着它需要加载,除非在这种情况下只加载Contact实体的“Name”属性,而不是整个Contact实体,如果我要使用上下文。 Addresses.include( “联系方式”)?它是否使得这样的查询比使用.include()的预先加载更有效?

一些澄清将不胜感激。

2 个答案:

答案 0 :(得分:2)

延迟加载,急切加载和显式加载在最常见的场景中有效。投影是替换急切加载,因为它还可以通过单个查询加载相关实体。如果需要使用某些复杂查询加载实体,则使用投影是有意义的,因为在这些情况下,急切加载不起作用。如果您需要,请使用投影:

  • linq查询中的任何类型的连接或聚合。据我所知,一旦开始使用手动连接,就会忽略Include
  • 导航属性中的任何类型的过滤或排序。 Include只能从导航属性加载所有相关实体而不进行任何排序。一旦您需要在相关实体上应用任何条件或顺序,您就无法使用Include并且必须使用投影。

答案 1 :(得分:1)

这是一种懒惰的评价,因为它会在枚举地址之前执行。

预先加载通常用于描述预加载的实体对象的导航属性,但在这种情况下,当您投射到匿名类型时,您不会直接实现任何实体对象。

如果你访问a.Contact.Name而不是Name,你很可能会因为你没有急切地加载Address的Contact对象而导致另一个数据库命中,你专门选择并将Name属性投影到一个匿名对象上。 / p>