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

Raf*_*mez 3 sql linq database performance entity-framework

我正在学习 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)))
Run Code Online (Sandbox Code Playgroud)

将返回所有processesType=21State=0Vdat>01.01.2017其中 a processAdress= AdrNr0201 和 a position= ArtId200。这里使用了导航属性并且必须启用延迟加载。(我认为,由于需要加载相关数据,并且在访问导航道具时会加载)

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

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
Run Code Online (Sandbox Code Playgroud)

这里没有使用导航道具。

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

所以我的问题是:

  • 一种查询方式与另一种方式查询的主要区别是什么?
  • 使用其中之一时有什么规则需要遵循吗?
  • 在这种情况下或一般的 SQL 查询中,我如何才能扰乱性能呢?

Ger*_*old 5

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

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

使用其中之一时有什么规则需要遵循吗?

指导方针就是其中之一。往上看。

在这种情况下或一般的 SQL 查询中,我如何才能扰乱性能呢?

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

另请参阅:不要使用 Linq 的 Join。导航!

  • 导航属性还往往会导致大量嵌套查询,在某些情况下,我发现这可能会导致成本高昂的冗余连接。最好的策略可能是始终检查您编写的每个 LINQ 查询生成的 SQL。 (2认同)