4

エンティティフレームワーク4.1で小さな質問があります。

画像DTOのインターフェースがあります:

public interface IImage : IDtoBase
{
    string FullFilePath { get; set; }
    int Width { get; set; }
    int Heigth { get; set; }
    long ImageTypeId { get; set; }
    IImageType Type { get; set; }
}

コンテキストを構成するコードがあります:

// where TContext : DbContext, new()
private TInterface Invoke(Func<TContext, TInterface> callback)
{
    using (var context = new TContext())
    {
        context.Configuration.AutoDetectChangesEnabled = true;
        context.Configuration.LazyLoadingEnabled = true;
        context.Configuration.ProxyCreationEnabled = true;
        context.Configuration.ValidateOnSaveEnabled = true;

        context.Database.Connection.Open();

        return callback.Invoke(context);
    }
}

必要なDTOアイテムを取得するためのコードがあります:

public TInterface Get(long id)
{
    return Invoke(
        context =>
        {
            TDto dto = context.Set<TDto>().FirstOrDefault(x => (x.Id == id));
            return dto.Convert<TDto, TInterface>();
        }
    );
}

を設定context.Configuration.LazyLoadingEnabled = falseすると、画像DTOの「Type」プロパティはnullになります(大丈夫だと思います)。

が「true」の値の場合context.Configuration.LazyLoadingEnabled、画像DTOの「Type」プロパティは「using」ステートメント内で正しい値を持ちますが、このプロパティはコンテキストの破棄後に破棄されます-「ObjectContextインスタンスは破棄され、操作に使用できなくなりました接続が必要です。」

つまり、イメージDTOは存在する/破棄されますが、その「Type」プロパティはすでに破棄されています。

誰かが解決策を提供できますか?「Type」プロパティを破棄しないでください(「Dispose」パターンの代わりに「using」ステートメントを使用したい)?

4

1 に答える 1

4

まず、遅延読み込みがどのように機能するかを理解する必要があります。EF は、エンティティ クラスから継承するプロキシを作成することでこれを行い、ナビゲーション プロパティ アクセス動作をオーバーライドします。ナビゲーション プロパティに初めてアクセスするとき、プロキシ クラスがcontextを介してロードするロジックを持つ前にロードされなかった場合。したがって、プロキシ インスタンスはコンテキストへの参照を保持します。

実行がInvokeメソッドを離れると、コンテキストは破棄されます。そのため、プロキシはナビゲーション プロパティを遅延ロードできません。これを解決するためにできることがいくつかあります。

  • Eager ロード ナビゲーション プロパティ

メソッドを使用しIncludeて熱心にロードする

public TInterface Get(long id)
{
    return Invoke(
        context =>
        {
            TDto dto = context.Set<TDto>().Include(t => t.Type)
                  .FirstOrDefault(x => (x.Id == id));

            return dto.Convert<TDto, TInterface>();
        }
    );
}
  • コンテキストの有効期間を制御する メソッド内ですぐにコンテキストを破棄せずInvokeに、データ アクセスの完了後に破棄される既存のコンテキスト インスタンスを使用できます。これは、IoC/DI フレームワークで実行できます。Web プロジェクトの場合、通常、有効期間は 1 回のリクエストに制限されます。
于 2012-06-12T00:05:50.407 に答える