1

私はMVCWebアプリケーションにLinqToSqlを使用しています。多くの人がほぼ同時にWebアプリにアクセスすると、An item with the same key has already been added.エラーが発生します。このエラーのスタックは次のようになります。

[ArgumentException: An item with the same key has already been added.]
   System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add) +12673712
   System.Data.Linq.DataContext.GetTable(MetaTable metaTable) +286
   System.Data.Linq.DataContext.GetTable() +100
   CableSense.Domain.Repository.Concrete.RoleRepository.GetRolesForUser(String userName) in c:\BuildAgent\work\271278ff356daf1\CableSense.Domain\Repository\Concrete\RoleRepository.cs:84

これは、.netRoleProviderのカスタム実装であるRoleRroviderクラスからのみ発生します。そこで、私のctorはNinjectから次のようなリポジトリを取得します。

    public CustomRoleProvider()
    {
        _roleRepository = NinjectMVC3.Resolve<IRoleRepository>();
    }

エラーが発生するメソッド:

    public override string[] GetRolesForUser(string username)
    {
        return _roleRepository.GetRolesForUser(username);
    }

私のリポジトリでは、データを返すlinqクエリに他なりません。リポジトリはコンテキストを内部的にインスタンス化し、静的または共有されるものはありません。

なぜこれが起こる可能性があるのか​​、何か考えはありますか?

4

2 に答える 2

1

Ninjectにこれを行うオプションがあるかどうかはわかりませんが、resolveを呼び出すたびに、必要なコンテキストの新しいインスタンスが返されるはずです。

これは、EFコンテキストがスレッドセーフではないという事実が原因です。

たとえば、選択したIoCとしてCastle.Windsorを使用し、LifeStyleオプションがあり、Singleton(デフォルト)ではなくTransientに設定すると、目的の動作が得られます。

于 2012-05-11T07:49:26.333 に答える
0
private object _lockHandle=new object();

 public override string[] GetRolesForUser(string username)
    {
lock(_lockHandle){
        return _roleRepository.GetRolesForUser(username);
}
    }
于 2012-05-11T07:29:51.870 に答える