简体   繁体   English

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

[英]Modeling a many-to-many relationship between 3 tables with Code First

I have the following 3 entities: 我有以下3个实体:

  • User 用户
  • Account 帐户
  • Role 角色

And the relationship goes like 这种关系就像

  • One user can have many accounts 一个用户可以拥有多个帐户
  • One account can belong to many users 一个帐户可以属于许多用户
  • Each user has a role in an account 每个用户都在帐户中拥有角色
  • There are a few, predefined roles (defined in the enum Roles) 有一些预定义的角色(在枚举角色中定义)

I got this far: 我到目前为止:

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; }
}

Every time an user registers, they also create an account, so I thought of this: 每次用户注册时,他们也会创建一个帐户,所以我想到了这个:

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();
 }

But I am not sure how to tie the role to the user to the account, so I can get the role an user has in an account. 但我不确定如何将角色与用户绑定到帐户,因此我可以获得用户在帐户中的角色。

For example: 例如:

Consider 3 users and 3 accounts: 考虑3个用户和3个帐户:

  • Account1 = (User1, Owner), (User2, TeamMember) Account1 =(User1,Owner),(User2,TeamMember)
  • Account2 = (User2, Owner) Account2 =(User2,所有者)
  • Account3 = (User3, Owner), (User1, ReadOnlyMember) Account3 =(User3,Owner),(User1,ReadOnlyMember)

Following @IvanStoev's answer, I got this: 按照@ 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();
}

Should I be saving the UserAccount object (as a DbContext<UserAccount> )? 我应该保存UserAccount对象(作为DbContext<UserAccount> )吗?

  • One user can have many accounts 一个用户可以拥有多个帐户
  • One account can belong to many users 一个帐户可以属于许多用户
  • Each user has a role in an account 每个用户都在帐户中拥有角色

The automatic link table does not work for scenarios like this when you need to associate additional information ( Role in this case) with the User - Account link. 当您需要将其他信息(在本例中为Role )与User - Account链接相关联时,自动链接表不适用于此类方案。

So instead of automatic many-to-many association you need to use two one-to-many associations with explicit link entity like this: 因此,您需要使用与显式链接实体的两个one-to-many关联,而不是自动many-to-many关联,如下所示:

Model: 模型:

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; }
}

Configuration: 组态:

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);

You can create a new UserAccount in a several ways. 您可以通过多种方式创建新的UserAccount

One way is to add it to one of the child UserAccounts collections. 一种方法是将其添加到其中一个子UserAccounts集合中。 In your example, account.UserAccounts.Add(uc); 在您的示例中, account.UserAccounts.Add(uc); followed by context.Accounts.Add(account) will automatically add it to context.UserAccounts , user.UserAccounts and role.UserAccounts . 然后是context.Accounts.Add(account)会自动将其添加到context.UserAccountsuser.UserAccountsrole.UserAccounts

Another way is to use context.UserAccounts.Add(uc); 另一种方法是使用context.UserAccounts.Add(uc); in which case it will be automatically added to user , account and role child UserAccounts collections. 在这种情况下,它将自动添加到useraccountroleUserAccounts集合中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM