使用Code First模拟3个表之间的多对多关系

时间:2016-07-24 15:47:41

标签: c# entity-framework

我有以下3个实体:

  • 用户
  • 帐户
  • 作用

这种关系就像

  • 一个用户可以拥有多个帐户
  • 一个帐户可以属于许多用户
  • 每个用户都有帐户中的角色
  • 有一些预定义的角色(在枚举角色中定义)

我到目前为止:

public class User
{
    public int Id { get; set; }
    public ICollection<Account> Accounts { get; set; }
}

public class Account
{
    public int Id { get; set; }
    public ICollection<User> Users { get; set; }
}

public class Role
{
    public int Id { get; set; }
    public string RoleName { get; set; }
    public virtual ICollection<User> Users { get; set; }
    public virtual ICollection<Account> Accounts { get; set; }
}

每次用户注册时,他们也会创建一个帐户,所以我想到了这个:

public async Task AddAccountAsync(User user, string accountName)
{
    Account account = new Account(user, accountName);
    Role role = new Role(Roles.Owner);
    Accounts.Add(account);
    user.Accounts.Add(account);
    Entry(user).State = EntityState.Modified;
    await SaveChangesAsync();
 }

但我不确定如何将角色与用户绑定到帐户,因此我可以获得用户在帐户中的角色。

例如:

考虑3个用户和3个帐户:

  • Account1 =(User1,Owner),(User2,TeamMember)
  • 帐户2 =(用户2,所有者)
  • Account3 =(User3,Owner),(User1,ReadOnlyMember)

按照@ IvanStoev的回答,我得到了这个:

public async Task AddAccountAsync(User user, string accountName)
{
   Role role = new Role(Roles.Owner);
   Account account = new Account(model.AccountCurrency, model.AccountName, model.Description);
   UserAccount uc = new UserAccount
   {
       User = user,
       Account = account,
       Role = role
   };
   account.UserAccounts.Add(uc);
   Accounts.Add(account);

   user.UserAccounts.Add(uc);
   Entry(user).State = EntityState.Modified;
   await SaveChangesAsync();
}

我应该保存UserAccount对象(作为DbContext<UserAccount>)吗?

1 个答案:

答案 0 :(得分:7)

  
      
  • 一个用户可以拥有多个帐户
  •   
  • 一个帐户可以属于许多用户
  •   
  • 每个用户都有帐户中的角色
  •   

当您需要将其他信息(在这种情况下为Role)与User - Account链接相关联时,自动链接表不适用于此类方案。

因此,您需要使用与显式链接实体的两个many-to-many关联,而不是自动one-to-many关联,而不是:

型号:

public class User
{
    public int Id { get; set; }
    public ICollection<UserAccount> UserAccounts { get; set; }
}

public class Account
{
    public int Id { get; set; }
    public ICollection<UserAccount> UserAccounts { get; set; }
}

public class UserAccount
{
    public int UserId { get; set; }
    public int AccountId { get; set; }
    public int RoleId { get; set; }
    public User User { get; set; }
    public Account Account { get; set; }
    public Role Role { get; set; }
}

public class Role
{
    public int Id { get; set; }
    public string RoleName { get; set; }
    public ICollection<UserAccount> UserAccounts { get; set; }
}

配置:

modelBuilder.Entity<UserAccount>()
    .HasKey(e => new { e.UserId, e.AccountId });

modelBuilder.Entity<UserAccount>()
    .HasRequired(e => e.User)
    .WithMany(e => e.UserAccounts)
    .HasForeignKey(e => e.UserId);

modelBuilder.Entity<UserAccount>()
    .HasRequired(e => e.Account)
    .WithMany(e => e.UserAccounts)
    .HasForeignKey(e => e.AccountId);

modelBuilder.Entity<UserAccount>()
    .HasRequired(e => e.Role)
    .WithMany(e => e.UserAccounts)
    .HasForeignKey(e => e.RoleId);

您可以通过多种方式创建新的UserAccount

一种方法是将其添加到其中一个子UserAccounts集合中。在您的示例中,account.UserAccounts.Add(uc);后跟context.Accounts.Add(account)会自动将其添加到context.UserAccountsuser.UserAccountsrole.UserAccounts

另一种方法是使用context.UserAccounts.Add(uc);,在这种情况下,它会自动添加到useraccountroleUserAccounts个集合中。