ASP.NET MVC 4 Code-First IdentityUserRole,带有额外的主键3路关系

时间:2016-02-11 02:33:44

标签: c# asp.net-mvc-4 ef-code-first asp.net-identity automatic-migration

我一直在网上搜索数星期,希望找到解决我在使用.NET Identity框架创建数据库时遇到的问题的解决方案。

我找到的最近的相关问题之一是:Customised IdentityUserRole primary key

但是我使用的是自动迁移,以避免手动指定Up和Down方法。

我想要实现的是在我的UserRoles表中有一个额外的主键,它来自IdentityUserRoles,实现如下:

public class UserRole : IdentityUserRole
{
    [Key, ForeignKey("Company")]
    public string CompanyId { get; set; }

    public Company Company { get; set; }
}

我的OnModelCreating方法如下所示:

...
public DbSet<UserRole> UserRolesExt { get; set; }
...

protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    modelBuilder.Entity<User>().ToTable("Users");
    modelBuilder.Entity<IdentityUserRole>().ToTable("UserRoles");
    // Failed attempt to make property a primary key below:
    modelBuilder.Entity<UserRole>().HasKey(ur => ur.CompanyId).ToTable("UserRoles");
    modelBuilder.Entity<IdentityUserLogin>().ToTable("UserLogins");
    modelBuilder.Entity<IdentityUserClaim>().ToTable("UserClaims");
    modelBuilder.Entity<IdentityRole>().ToTable("Roles");
}

然而,该表最终看起来像这样:

http://i.imgur.com/n0dne7O.png

令我困惑的一件事是,它也被设置为可以为空的类型,但我有一种感觉,它引用了我的自定义公司类,它只包含原始数据类型。

我之所以想要这个实体的三方关系,是因为我的系统将包含多个公司中的多个用户,每个用户可以是多个公司的成员,同时也是该用户的个人角色在给定的公司内。

如果可能,我会非常希望避免制作我自己的UserStores和RoleStores等,这是我发现的一些解决方案,因为我想保持简单,所以说。

我的一个类中没有派生自Identity类的示例如下所示,并且按预期工作:

public class UserModule
{
    [Key, ForeignKey("User"), Column(Order = 0)]
    public string UserId { get; set; }
    public User User { get; set; }

    [Key, ForeignKey("Module"), Column(Order = 1)]
    public string ModuleId { get; set; }
    public Module Module { get; set; }
}

我尝试在我的UserRole类中摆弄各种版本的数据注释但没有任何运气。是否真的无法扩展此UserRole类以获得额外的主键,而无需进行主要自定义?

还应该注意的是,如果我只是在创建后手动编辑数据库,我可以使所有三个属性主键和表按预期工作。但我非常想知道如何让它正常工作,以便说出来。

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

如果我理解正确,您希望向IdentityUserRole类添加一个额外的列,并将该列作为主键的一部分。为此,您必须稍微修改OnModelCreating方法,如下所示:

modelBuilder.Entity<UserRole>()
            .ToTable("UserRoles")
            .HasKey(r => new { r.UserId, r.RoleId, r.CompanyId })
            .HasRequired(r => r.Company).WithMany();

此代码实质上重新定义了主键,还包含CompanyId列,然后将其作为必填字段。

您还应该从[Key, ForeignKey("Company")]属性中删除CompanyId属性,以防止注释干扰流畅的语法。我不认为modelBuilder.Entity<IdentityUserRole>().ToTable("UserRoles");行也是必要的,您可以尝试删除它。