0

我试图先用代码或先用 db 弄清楚如何获得一个代表这种情况的模型。我正在使用实体框架 5.0。

我有一个用户,可能有也可能没有与他们关联的单个帐户。如果他们与一个帐户相关,他们将扮演许多角色。

本质上,我需要:

用户 ==> 0,1 UserAccount 1 ==> * UserAccountRole * <== 1 AccountRole

UserAccount 表需要 UserID 上的唯一键 UserAccount 表有一个主键 UserID,AccountID UserAccountRole 有一个主键 UserID,AccountID,AccountRoleId

当我使用 DB First 时,模型不会选择 1=>0,1 在代码中,我首先无法弄清楚 Fluent API 的表示方式:

在此处输入图像描述

我可以这样做,还是我需要一个只有一个业务规则的多对多用户帐户表?

谢谢

4

2 回答 2

1

好的,我找到了答案,它有点复杂,所以我不确定我是否喜欢它。

要获得上面的表结构,您必须将 SystemUserAccount 创建为多对多。然后您需要在 SystemUserAccount 表的 UserId 列上创建一个单独的唯一 Key。我能找到运行它的唯一钩子是 DBInitializer 的 Seed 方法。这是代码:

public  class SystemUser
{
  public int Id { get; set; }
  public string Name { get; set; } 

  public ICollection<SystemUserAccount> SystemUserAccounts{get;set;}
}

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

public class SystemUserAccount
{
    public int UserId { get; set; }
    public int AccountId { get; set; }

    public virtual ICollection<AccountRole> AccountRoles { get; set; }

    public SystemUser SystemUser { get; set; }
    public Account UserAccount { get; set; }
}

public class AccountRole
{
    public int Id { get; set; }
    public String Name { get; set; }

    public virtual ICollection<SystemUserAccount> UserAccounts { get; set; }
}

然后这个上下文:

 public DbSet<SystemUser> SystemUser { get; set; }
    public DbSet<SystemUserAccount> SystemUserAccount { get; set; }
    public DbSet<Account> Account { get; set; }
    public DbSet<AccountRole> AccountRole { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<SystemUserAccount>()
            .HasKey(sua => new { sua.UserId, sua.AccountId });

        modelBuilder.Entity<SystemUserAccount>()
            .HasRequired(sua => sua.SystemUser)
            .WithMany(u => u.SystemUserAccounts)
            .HasForeignKey(u => u.UserId);

        modelBuilder.Entity<SystemUserAccount>()
            .HasMany(sua => sua.AccountRoles)
            .WithMany(ar => ar.UserAccounts)
            .Map(m =>
                     {
                         m.ToTable("UserAccountRole");
                         m.MapLeftKey("UserId", "AccountId");
                         m.MapRightKey("AccountRoleId");
                     }
            );
    }

最后在数据库初始化程序的种子方法中:

public  class DatabaseInitializer : DropCreateDatabaseAlways<PeopleContext>
{
  protected override void Seed(PeopleContext context)
  {
        context.Database.ExecuteSqlCommand("ALTER TABLE SystemUserAccounts ADD CONSTRAINT uc_User UNIQUE(UserId)"); 
  }
}

然后只需在程序中调用 DatabaseInitializer:

  Database.SetInitializer<PeopleContext>(new DatabaseInitializer());

这给了我 OP 中显示的表结构。我不确定它在查询中的表现如何。

我希望它可以帮助任何试图这样做的人。

塔尔

于 2012-08-20T13:31:47.177 回答
0

我不确定我是否理解您的目标 - 但我认为您想要的是 3 个主要类 -并且User,使用 UserAccountRole 的多对多关系表,这只是将 UserAccounts 映射到 AccountRoles。如果我对您的目标的理解有误,请用更多细节更新问题。UserAccountAccountRole

如果是这样,我用这些类完成了这个:

public class User
{
    public int UserId { get; set; }
    public virtual UserAccount UserAccount { get; set; }
}

public class UserAccount
{
    public int UserId { get; set; }
    public int AccountId { get; set; }
    public virtual ICollection<AccountRole> AccountRoles { get; set; }

    public virtual User User { get; set; }

}

public class AccountRole
{
    public int AccountRoleId { get; set; }
    public virtual ICollection<UserAccount> UserAccounts { get; set; }
}

这个映射:

public class Model : DbContext
{
    public DbSet<User> Users { get; set; }
    public DbSet<UserAccount> UserAccounts { get; set; }
    public DbSet<AccountRole> AccountRoles { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>()
            .HasOptional(u => u.UserAccount)
            .WithRequired(ua => ua.User);

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

        modelBuilder.Entity<UserAccount>()
            .HasMany(ua => ua.AccountRoles)
            .WithMany(ar => ar.UserAccounts)
            .Map(map =>
                {
                    map.ToTable("UserAccountRole");
                    map.MapLeftKey("UserId", "AccountId");
                    map.MapRightKey("AccountRoleId");
                });

    }
}

这创建了类,以及具有您正在寻找的复合键的多对多表:

在此处输入图像描述

于 2012-08-17T17:44:51.770 回答