スキーマについて説明した以前の質問から続けます(便宜上、ここで繰り返します)。
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();
}