0

スキーマについて説明した以前の質問から続けます(便宜上、ここで繰り返します)。

Parties ( PartyId, ClientId, AddressId, DateTime )
Tents ( PartyId, TentDetails... )
Clowns ( PartyId, AddressId, ClownDetails... )
SecurityAgentAssignment ( PartyId, AgentId, fromTime, untilTime )
Addresses ( AddressId, Street, City, State )

....そして、同様のデザインのテーブルが他に約 10 あります。すべて と多対 1 の関係にありPartiesます。

私の ASP.NET MVC Web アプリケーションには、パーティーに関するすべての詳細を表示する [概要] ページがあります。私は EF1.0 を使用しているため、独自の熱心な読み込みを行う必要があります。私が使用しているロジックは次のとおりです。

Party dbParty = GetParty(partyId);

dbParty.Tents.EnsureLoaded();
dbParty.Clowns.EnsureLoaded();
foreach(Clown clown in dbParty.Clowns) clown.Address.EnsureLoaded();
dbParty.Security.EnsureLoaded();
foreach(SecurityAgentAssignment assignment in dbParty.Security) assignment.Agent.EnsureLoaded();
// and the 10 other relationships too

上記のコードの実行には約 3 秒かかります。これが熱心な読み込みではなく、遅延読み込みであることを考えると、確かに約 15 個の単純な SELECT クエリを起動するだけで完了するはずですか?

SQL Server Profiler をインストールしていません。また、.Load代わりにIQueryable.

これらの拡張メソッドをヘルパーとして使用します。

private static readonly R.FieldInfo    _entityReferenceContext = typeof(RelatedEnd).GetField("_context", R.BindingFlags.Instance | R.BindingFlags.NonPublic );
private static readonly R.PropertyInfo _relatedEndOwner        = typeof(RelatedEnd).GetProperty("Owner", R.BindingFlags.Instance | R.BindingFlags.NonPublic );

private static Boolean IsAttached(this RelatedEnd relatedEnd) {

    Object context =  _entityReferenceContext.GetValue( relatedEnd );
    return context != null;
}

public static TEntity EnsureLoaded<TEntity>(this EntityReference<TEntity> eref) where TEntity : class, IEntityWithRelationships {

    // EntityReference<TEntity> derives from RelatedEnd.
    RelatedEnd erefAsRelatedEnd = (RelatedEnd)eref;

    erefAsRelatedEnd.EnsureLoaded();

    return eref.Value;
}

public static void EnsureLoaded(this RelatedEnd end) {

    IEntityWithRelationships owner       = (IEntityWithRelationships)_relatedEndOwner.GetValue( end, null );
    EntityObject             ownerEntity = owner as EntityObject;

    if( ownerEntity != null ) {

        if( ownerEntity.EntityState == EntityState.Added || ownerEntity.EntityState == EntityState.Detached ) return; // calling .Load on a Added object causes an exception.
    }

    if( end.IsAttached() && !end.IsLoaded ) end.Load();
}
4

1 に答える 1

0

この質問は意味がありません。VPN 接続を介してデータベース サーバーに接続していました。私のコンピュータとデータベース サーバー間の ping 時間は 50 ミリ秒程度だったので問題ないと思っていましたが、SQL Server の通信速度は忘れてしまいました。一度に約 60 のクエリを起動することを考えると、60 * 50ms == 3000ms.

サーバーと同じ LAN でアプリケーションを再試行したとき (ping 時間 < 1 ミリ秒)、ロード操作全体が 30 ミリ秒未満で実行され、それ以上の最適化は必要ありませんでした。問題が解決しました。

于 2013-05-15T21:59:26.667 に答える