2016-09-01 9 views
2

私は開発しているASP.Net MVCアプリケーションの一部としてEntity Frameworkに移動します。コードを先に使用すると、ユーザロールリストのために働く単純な多対多マッピングを取得しようとしています。エンティティフレームワーク多対多マッピング

私は以下のクラス(および関連データベーステーブルを)持っている

public class User 
{ 
    public int UserID { get; set; } 
    public string EmailAddress { get; set; } 
    // etc... 

    public virtual ICollection<Role> Roles { get; set; } 
} 

public class Role 
{ 
    public int RoleID { get; set; } 
    public string RoleName { get; set; } 

    public virtual ICollection<User> Users { get; set; } 
} 

public class UserRoles 
{ 
    public int UserRoleID { get; set; } 
    public int UserID { get; set; } 
    public int RoleID { get; set; } 
} 

と多対多の関係をマップOnModelCreatingオーバーライド...

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<User>() 
     .HasMany<Role>(u => u.Roles) 
     .WithMany(r => r.Users) 
     .Map(ur => { 
      ur.MapLeftKey("UserID"); 
      ur.MapRightKey("RoleID"); 
      ur.ToTable("UserRoles"); 
     }); 
} 

public DbSet<User> Users { get; set; } 

ユーザーが認証されます私は、現在認証されたUserオブジェクトをカスタムIPrincipalの実装の一部として利用可能にします。

public class MyPrincipal : IPrincipal 
{ 
    // User attached to this custom IPrincipal 
    public User User { get; set; } 
} 

。しかしGlobal.asax

protected void Application_AuthenticateRequest(object sender, EventArgs e) 
{ 
    // Get the FormsAuthentication cookie 
     HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName]; 

     // If the cookie exists 
     if (authCookie != null) 
     { 
      // Get the authentication ticket 
      FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value); 
      var identity = new GenericIdentity(authTicket.Name, "Forms"); 
      var principal = new WebStoresPrincipal(identity); 

      // Get the userdata from the ticket 
      string userData = ((FormsIdentity)(Context.User.Identity)).Ticket.UserData; 

      // Deserialize the JSON data 
      var serializer = new JavaScriptSerializer(); 
      principal.User = (User)serializer.Deserialize(userData, typeof(User)); 

      // Set the context user 
      Context.User = principal; 
     } 

} 

Userを利用できるようになり、認証要求段階 - 私が正しく理解するか、完全にポイントを逃していないよどこ多分これは - 私がアクセスしようにはUserが割り当てられていますが、これは空のコレクションですが、Entity FrameworkにRolesコレクションが移入されると予想していました。

だから、私は以下のデータを持っている与えられた:

Roles
RoleID、名前
1、管理者
2、コントリビュータ
3、証明リーダー

Users
ユーザーID、名前を等
1、ボブ・スミス
2、ジョーBloggs

UserRoles
UserRoleID、ユーザID、RoleID
1、1、1
2、2、3

私が見た場合、データが返されること予想を有するであろうUser 1の場合、は、Administratorロールの単一のエントリを含むRolesコレクションを参照してください。

明らかに、私はここで何か基本的なものを見逃していますが、何十ものウェブサイトを徘徊してしまったので、多対多を設定する以外には何も説明されていません。

+0

あなたの質問を編集して、どのようにユーザーを取得しているかを示してください。おそらくあなたは**さらに 'UserRoles'モデルは、このシナリオ –

+0

に**含める欠けているUserRolesが冗長である理由を説明してください? –

+0

@AdilMammadovに冗長化されたクエリ – weblar83

答えて

2

Userあなたがチケットから脱直列化しているようなオブジェクトは、データベースには添付されていません。その後、EFはRolesテーブルのRolesをこのオブジェクトにロードしません。

代わりにDbContextからユーザーをロードしてみてください。

// after "Deserialize the JSON data" 
var loadedUser = dbContext.Users.Find(principal.User.UserId); 

このオブジェクトには、移入されたロールコレクションが必要です。

+0

完璧!それは、治療を働く、ありがとう!私はAuthenticateRequestが呼び出されるたびにデータベースを照会することを本当に望んでいませんでしたが、イントラネットアプリケーションであれば、それは本当に問題ではないと思います。 – weblar83

+0

多分、LogOnアクションでのみロールをロードして(チケットに格納する)ことができます。これにより、ロールが変更された後に再度ログインする必要があります。 –

+0

私はこれを考えていましたが、ログアウトして再度ログインするのではなく、「オンザフライで」役割に反映されるという考えが好きです。 – weblar83

関連する問題