ASP.NET MVC 4 代码优先标识用户角色,具有额外的主键 3 向关系

本文关键字:关系 代码 MVC NET 角色 用户 标识 ASP | 更新日期: 2023-09-27 18:34:04

我已经在网上搜索了几个星期,希望找到解决我在使用 .NET 标识框架创建数据库时遇到的问题的方法。

我发现的最接近的相关问题之一是:自定义标识用户角色主键

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

我试图实现的是在我的UserRoles表中有一个额外的主键,该主键派生自IdentityUserRoles,实现如下所示:

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

我的 OnModelCreate 方法如下所示:

...
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");
}

但是,该表最终看起来像这样:

https://i.stack.imgur.com/Ziz0e.png

让我感到困惑的一件事是它也设置为可空类型,但我有一种感觉,指的是我的自定义 Company 类,该类仅包含原始数据类型。

我之所以希望此实体具有这种 3 向关系,是因为我的系统将包含多个公司中的多个用户,其中每个用户可以是多个公司的成员,因此该用户在给定公司中的个人角色也是如此。

如果可能的话,我非常想避免制作自己的UserStore和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 类以获得额外的主键,而不必进行重大自定义吗?

还应该注意的是,如果我在创建后简单地手动编辑数据库,我能够使所有三个属性成为主键,并且表按预期工作。但我非常想知道如何让它正常工作。

任何帮助将不胜感激!

ASP.NET MVC 4 代码优先标识用户角色,具有额外的主键 3 向关系

如果我

理解正确,您想在IdentityUserRole类中添加一个额外的列,并使该列成为主键的一部分。为此,您必须稍微修改OnModelCreating方法,如下所示:

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

此代码实质上是重新定义主键以包括CompanyId列,然后使其成为必填字段。

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