gpt4 book ai didi

entity-framework - 与ID上的.SingleOrDefault相比,DbSet.Find方法要慢得多

转载 作者:行者123 更新时间:2023-12-03 08:25:09 26 4
gpt4 key购买 nike

我有以下代码(数据库为SQL Server Compact 4.0):

Dim competitor=context.Competitors.Find(id)

当我对此进行概要分析时,Find方法需要300 + ms的时间才能从只有60条记录的表中检索竞争对手。

当我将代码更改为:
Dim competitor=context.Competitors.SingleOrDefault(function(c) c.ID=id)

然后,仅3毫秒即可找到竞争对手。

竞争对手类:
Public Class Competitor
Implements IEquatable(Of Competitor)

Public Sub New()
CompetitionSubscriptions = New List(Of CompetitionSubscription)
OpponentMeetings = New List(Of Meeting)
GUID = GUID.NewGuid
End Sub

Public Sub New(name As String)
Me.New()
Me.Name = name
End Sub

'ID'
Public Property ID As Long
Public Property GUID As Guid

'NATIVE PROPERTIES'
Public Property Name As String

'NAVIGATION PROPERTIES'
Public Overridable Property CompetitionSubscriptions As ICollection(Of CompetitionSubscription)
Public Overridable Property OpponentMeetings As ICollection(Of Meeting)
End Class

我使用流畅的API为 CompetitionSubscriptionsOpponentMeetings定义了多对多关系。
Competitor类的ID属性是Long,由Code First将其转换为具有数据表中主键的Identity列(SQL Server Compact 4.0)

这里发生了什么??

最佳答案

Find在内部调用DetectChanges,而SingleOrDefault(或通常任何查询)则不会。 DetectChanges是一项昂贵的操作,因此这就是Find较慢的原因(但是如果该实体已经加载到上下文中,它可能会变得更快,因为Find不会运行查询,而只是返回已加载的实体)。

如果要对许多实体使用Find(例如,在循环中),则可以像这样禁用自动更改检测(不能在VB中编写,因此是C#示例):

try
{
context.Configuration.AutoDetectChangesEnabled = false;
foreach (var id in someIdCollection)
{
var competitor = context.Competitors.Find(id);
// ...
}
}
finally
{
context.Configuration.AutoDetectChangesEnabled = true;
}

现在, Find不会在每次调用时都调用 DetectChanges,它应该和 SingleOrDefault一样快(如果实体已经连接到上下文,则应该更快)。

自动更改检测是一个复杂且有些神秘的主题。在这个分为四部分的系列文章中,可以找到详细的讨论:

(到第1部分的链接,到第2、3和4部分的链接在该文章的开头)

http://blog.oneunicorn.com/2012/03/10/secrets-of-detectchanges-part-1-what-does-detectchanges-do/

关于entity-framework - 与ID上的.SingleOrDefault相比,DbSet.Find方法要慢得多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11686225/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com