1

私のロールプロバイダーは、以下のクラスのように見えます(要約)。VS2012のIISExpressとSQL2012Expressを実行していますが、この役割プロバイダーのコードで、一見ランダムに見える多数の例外が発生します。

public class Educ8RoleProvider : RoleProvider
{
    private readonly Educ8DbContext _dbContext = new Educ8DbContext();
    private readonly Authorization _authorization;
    public Educ8RoleProvider()
    {
        _authorization = new Authorization(_dbContext);
    }
    public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
    {
        try
        {
            base.Initialize(name, config);
        }
        catch (Exception ex)
        {
            ErrorSignal.FromCurrentContext().Raise(ex);
            throw;
        }
    }
    public override bool IsUserInRole(string username, string roleName)
    {
        return GetRolesForUser(username).Any(r => r.ToLower() == roleName);
    }
    public override string[] GetRolesForUser(string username)
    {
        return _authorization.GetRolesForMember(username).Select(r => r.Name).ToArray();
    }
}

これが私のAuthorizationクラスのサンプルです:

public class Authorization
{
    private readonly Educ8DbContext _dbContext;
    private readonly IMemberRepository _memberRepository;
    private readonly IRoleRepository _roleRepository;
    private readonly IMemberRoleRepository _memberRoleRepository;
    public Authorization(Educ8DbContext context)
    {
        _dbContext = context;
        _memberRepository = new MemberRepository(_dbContext);
        _roleRepository = new RoleRepository(_dbContext);
        _memberRoleRepository = new MemberRoleRepository(_dbContext);
    }
    public IQueryable<Role> GetRoles()
    {
        return _roleRepository.ListAll();
    }
    public IQueryable<Role> GetRolesForMember(int memberId)
    {
        var roleIds = _memberRoleRepository.ListAll()
            .Where(mr => mr.MemberId == memberId)
            .Select(mr => mr.RoleId);
        return _roleRepository.ListAll()
            .Where(r => roleIds.Contains(r.Id));
    }
}

次の例外のうち、1時間に2〜3回発生します。プロジェクトを再開すると、次の問題が発生するまで、問題はすぐに解決します。

  • 'ConnectionString'プロパティを変更することはできません。接続の現在の状態は閉じられています。
  • モデルの作成中は、コンテキストを使用できません。
  • 基になるプロバイダーがOpenで失敗しました。

プロジェクトの他の場所では、データアクセスの問題がまったくないことは注目に値するかもしれません。

これを引き起こしている可能性のあるものについての提案は大歓迎です。

4

1 に答える 1

5

Gert Arnoldは、彼のコメントで正しい方向に進んでいます。RoleProviderシングルトンとして実行されることを理解する必要があります。アプリを再起動するたびに、このクラスの新しいインスタンスが構築されます。アプリケーションが実行されている限り、この単一のインスタンスを使用し続けます。

このクラスがシングルトンとして実行されることに気付く前に、私はあなたの質問と同じ種類の例外を取得していました。その知識を身に付けたら、これらの例外をなくすことは難しくありません。

public class Educ8RoleProvider : RoleProvider
{
    //private readonly Educ8DbContext _dbContext = new Educ8DbContext();
    //private readonly Authorization _authorization;
    public Educ8RoleProvider()
    {
        //_authorization = new Authorization(_dbContext);
    }

    private Authorization GetAuthorization()
    {
        return new Authorization(new Educ8DbContext());
    }

    public override void Initialize(string name, NameValueCollection config)
    {
        try
        {
            base.Initialize(name, config);
        }
        catch (Exception ex)
        {
            ErrorSignal.FromCurrentContext().Raise(ex);
            throw;
        }
    }
    public override bool IsUserInRole(string username, string roleName)
    {
        return GetRolesForUser(username)
            .Any(r => r.ToLower() == roleName);
    }
    public override string[] GetRolesForUser(string username)
    {
        return GetAuthorization().GetRolesForMember(username)
            .Select(r => r.Name).ToArray();
    }
}

基本的に、各メソッド呼び出しがRoleProviderまったく新しいDbContextインスタンスで機能することを確認する必要があります。このように、シングルトンは古くなるRoleProviderシングルにぶら下がっていません。DbContext

于 2012-10-01T21:40:03.213 に答える