0

ライブ環境にデプロイされた新しいアプリケーションの作成が完了しましたが、グローバルエラーハンドラーがこれらの例外を 1 日に数回検出しています。これらのエラーはバッチで発生し、太字の 4 つのエラーの 1 つです。

MVC 4、IIS 6、Windows Server 2003、.Net .4.0、EF 5 (NuGet の最新版)

タイプ「ARandomModelInMyContext」が複数回マップされています。

インデックスが範囲外でした。負ではなく、コレクションのサイズより小さくなければなりません。

Parameter name: index
System.ThrowHelper.ThrowArgumentOutOfRangeException() at System.Data.Metadata.Edm.MetadataCollection`1.get_Item(Int32 index) at System.Data.Mapping.DefaultObjectMappingItemCollection.ContainsMap(GlobalItem cspaceItem, ObjectTypeMapping& map) at

モデルの作成中はコンテキストを使用できません。

System.Data.Entity.Internal.LazyInternalContext.InitializeContext() at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType) at System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()

基になるプロバイダーが Open で失敗しました。接続は閉じられませんでした。接続の現在の状態は接続中です。

アプリケーションの構造は、サービス層とリポジトリ層を備えた非常に標準的な MVC4 アプリケーションです。

  • サービスはコンストラクターでリポジトリを作成します
  • リポジトリは、次のようにリポジトリ コンストラクターで新しいコンテキストを作成します。

public class MyRepository : BaseRepository<MyModel>, IMyRepository

コンストラクターを使用する場合:

public MyRepository() : base(new MyEntities())
{
}

ベース リポジトリは次のようになります。

public class BaseRepository<TEntity> where TEntity : class
{
    internal CRMEntities Context;
    internal DbSet<TEntity> dbSet;
    public BaseRepository(MyEntities context)
    {
        this.Context = context;
        dbSet = context.Set<TEntity>();
    }
}

スレッドや非同期を直接使用していないため、同時実行の問題は発生しません。

何か案は?リポジトリ構造を改善できますか? すべてのコンストラクターを DI 対応にしましたが、IoC コンテナーはまだ使用していません。

リポジトリ内のコンテキストの構築をロックでラップする価値はありますか? 例えば:

public class BaseRepository<TEntity> where TEntity : class
{
    internal MyEntities Context;
    internal DbSet<TEntity> dbSet;
    private static object _lock = new object();

    public BaseRepository(MyEntities context)
    {
        lock (_lock)
        {
            this.Context = context;
            dbSet = context.Set<TEntity>();
        }
    }
 }
4

1 に答える 1

1

リポジトリ(したがってコンテキスト)が複数のリクエストで使用されているように見えます。これが true の場合、これは同じコンテキスト インスタンスのマルチスレッド使用であり、サポートされていません。コンテキストはスレッドセーフではありません。初期化だけをロックするだけでは不十分です。(また、 Set を呼び出してもコンテキストは初期化されません。) コンテキストへのすべてのアクセスを保護するか、有効期間が短いコンテキスト インスタンスを持つリクエスト モデルごとにコンテキストを適切に使用する必要があります。

于 2012-11-07T17:36:15.423 に答える