35

次のコードがあります (データベースは SQL Server Compact 4.0 です):

Dim competitor=context.Competitors.Find(id)

これをプロファイリングすると、Find メソッドはわずか 60 レコードのテーブルから競合他社を取得するのに 300 ミリ秒以上かかります。

コードを次のように変更すると:

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 を使用しCompetitionSubscriptionsて多対多の関係を定義しました。OpponentMeetings

クラスの ID プロパティはCompetitorLong であり、Code First によってデータテーブルの主キーを持つ Identity 列に変換されます (SQL Server Compact 4.0)

ここで何が起こっているのですか??

4

1 に答える 1

58

FindDetectChanges内部的に呼び出します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(エンティティが既にコンテキストにアタッチされている場合は高速です)。

自動変化検出は複雑でやや不可解なテーマです。この 4 部構成のシリーズでは、非常に詳細な議論を見つけることができます。

(パート 1 へのリンク、パート 2、3、4 へのリンクはその記事の冒頭にあります)

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

于 2012-07-27T12:54:52.730 に答える