【问题标题】:Modeling a many-to-many relationship between 3 tables with Code First使用 Code First 对 3 个表之间的多对多关系建模
【发布时间】:2016-07-24 15:47:40
【问题描述】:

我有以下 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)
  • Account2 = (User2, Owner)
  • 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&lt;UserAccount&gt;)吗?

【问题讨论】:

  • User 可以在没有Role 的情况下拥有Account 吗?您应该提供更多详细信息,如果您提供您想要的示例,那就更好了。
  • @TaherRahgooy 不,用户需要帐户中的角色。我将添加一个示例

标签: c# entity-framework


【解决方案1】:
  • 一个用户可以有多个帐户
  • 一个帐号可以属于多个用户
  • 每个用户在一个帐户中都有一个角色

当您需要将附加信息(在本例中为Role)与User - Account 链接关联时,自动链接表不适用于此类情况。

因此,您需要使用两个带有显式链接实体的 one-to-many 关联,而不是自动的 many-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集合中。

【讨论】:

  • 这看起来不错。您能否添加一个示例,说明我将如何创建新用户/帐户?我有一个猜测,但我想确定
  • UserAccount 添加到其中一个子集合就足够了(就像通常的one-to-many 案例一样)。在您的示例中,account.UserAccounts.Add(uc); 应该足够了。
  • 谢谢你的回答,正是我要找的东西
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多