2012-02-09 10 views
3

プロジェクト用にカスタムRoleProviderを実装しました。 RoleProviderは機能しますが、ユーザーロールを取得するために使用するリポジトリは、ビルド後にのみ作成されます。私がログオフしたときに、ユーザのロールを再度変更しても、ユーザはまだ古いロールを保持しています。カスタムRoleProviderは自分のリポジトリオブジェクトをキャッシュし続けます

public class CmsRoleProvider : RoleProvider 
{ 
    private EntityDB _db { get; set; } 

    public CmsRoleProvider() 
    { 
     _db = new EntityDB(); 
    } 

    public override string[] GetRolesForUser(string username) 
    { 
     var user = _db.Users.Where(u => u.EmailAddress == username).SingleOrDefault(); 
     var roles = user.UserRoles.Select(u => u.Role.Name).ToList<string>(); 

     return roles.ToArray(); 
    } 
} 

上記のサンプルでは、​​ユーザーはプロジェクトをビルドした後にのみ正しい役割を取得します。 GetRolesForUser関数内でリポジトリを作成すると、正常に動作します。

キャッシュの問題は解決しましたか?誰がこれで私を助けることができます。

+0

どのようにユーザーの役割を変更していますか? –

+0

データベースに直接ロールを追加または削除します。 – jpderooy

+1

だから、私の答えを見て、理解していない場合は、あなたが理解していないことを教えてください。 =) –

答えて

7

ASP.NETは、RoleProviderの単一インスタンスのみを作成します。そのため、あなたの文脈も長く存続します。短命の文脈を持つ方が良い。

public class CmsRoleProvider : RoleProvider 
{   
    private EntityDB GetContext() 
    { 
     return new EntityDB(); 
    } 

    public override string[] GetRolesForUser(string username) 
    { 
     using(var db = GetContext()) 
     { 
      var user = db.Users.Where(u => u.EmailAddress == username) 
          .SingleOrDefault(); 
      var roles = user.UserRoles.Select(u => u.Role.Name).ToList<string>(); 

      return roles.ToArray(); 
     } 
    } 
} 

問題は、コンテキストが読み込まれたユーザーを追跡することです。コンテキストによってすでに追跡されているユーザーを要求すると、既存のインスタンスが戻されます。したがって、それに関連付けられたUserRolesが返されます。

+0

ありがとう! 'EntityDB _db = new EntityDB();'を 'GetRolesForUser'メソッドの中に入れて修正しました。あなたの提案はよりエレガントです:) – jpderooy

+1

@jpderooy 'using'ブロックの中に' EntityDB _db = new EntityDB();をトラップするのを忘れないでください。これを受け入れられた答えとしてマークすることができます。 – Eranga

+0

素早くお返事ありがとうございます! – jpderooy

2

問題はコンテキスト参照です。コンテキスト(EntityDB)の参照を作成すると、コンテキストからロールを取得するメソッドのうち、この参照は同じです。つまり、選択されたすべてのデータは、選択が行われるため同じになります。データベースにない文脈(これはEFへの道であり、常にデータベースには行きません)。あなたが(ロールで)行う変更は別のコンテキストで行われたため、適切なコンテキストを取得するためには、コンテキストの新しいインスタンスを作成する必要があります。使用してkeyworkを用いた方法の中にそれを実行します。

using (var database = new EntityDB()) 
{ 
    // Get your roles and return them 
} 
+0

説明をありがとう! – jpderooy

+0

もしそれが役に立つのであれば、同じ問題を抱えている人を助けるために投票することができます。とにかく、いつでも歓迎です! =) –

+0

私はここで初心者ですから、投票するのにもっと評判が必要です;) – jpderooy

関連する問題