使用EF中的连接或导航属性的差异

时间:2018-01-27 22:31:03

标签: sql database performance entity-framework linq

我正在学习EF,我正在尝试了解何时使用哪种类型的查询。

例如此查询:

From fe In Processes.Where(Function(process) CBool(process.Type = 21 And 
                                            process.State = 0 And
                                            process.VDat > #2017/01/01# And
                                            process.ProcessAdresses.Any(Function(adr) adr.AdrNr = "0201") And
                                            process.ProcessPorisitions.Any(Function(pp) pp.ArtID = 200)))

将返回processesType=21State=0的所有Vdat>01.01.2017processAdress AdrNr = 0201,position 1}} ArtId = 200。 这里使用导航属性并且必须启用延迟加载。 (我认为,因为相关数据需要加载,并且它将在访问导航道具时)

现在我可以使用连接表达相同的查询:

From fe In Processes.Where(
            Function(process) CBool(
                process.Art = 215 And
                process.State = 0 And
                process.VDat > #2017/01/01#))
     Join adr In ProcessAdresses.Where(
             Function(adr) adr.AdrNr = "020107")
         On fe.VID Equals vadr.VID
     Join pp In ProcessPorisitions.Where(
             Function(pp) pp.ArtID = 20004993)
         On fe.VID Equals vpos.VID
     Group  By fe Into Group
     Select fe

这里没有使用导航道具。

我试图使用LinqPad测量/分析性能,但我只能看到创建的SQL查询的差异,而不费力......

所以我的问题是:

  • 查询一种查询另一种方式的主要区别是什么?
  • 使用其中一个时是否有任何规则要遵循?
  • 如何在这种情况下或一般的SQL查询中混乱性能?

2 个答案:

答案 0 :(得分:2)

  

查询一种查询另一种方式的主要区别是什么?

联接更难阅读,更容易出错。 EG第二个查询返回与第一个查询相同的数据吗?

  

使用其中一个时是否有任何规则要遵循?

尽可能使用导航属性。

  

如何在这种情况下或一般的SQL查询中混淆性能?

不正确的连接可能导致性能不佳,复杂的LINQ查询可能会导致意外复杂的SQL。此外,Eager加载太多相关实体会导致昂贵的查询。

答案 1 :(得分:2)

  

查询一种查询另一种方式的主要区别是什么?

一看你的代码就足够了。使用导航属性可使代码更易于理解且更易于维护。此外,显式连接容易出错。加入错误的ID属性很容易(我已经看到它发生了)。最后,如果您有更多类似的查询,它会导致重复的代码。

  

使用其中一个时是否有任何规则要遵循?

指南DRY就是其中之一。见上文。

  

如何在这种情况下或一般的SQL查询中混淆性能?

这可能是规则(指南)的唯一例外。非强制实体的导航属性将被转换为外连接。外连接可能比内连接更差。因此,当性能至关重要时,应该从最终结果中过滤掉空引用,您可以使用显式连接语句,覆盖导航属性。

另请参阅:Don't use Linq's Join. Navigate!