我已经在网上搜索了几个星期,希望找到解决我在使用 .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 类以获得额外的主键,而不必进行重大自定义吗?
还应该注意的是,如果我在创建后简单地手动编辑数据库,我能够使所有三个属性成为主键,并且表按预期工作。但我非常想知道如何让它正常工作。
任何帮助将不胜感激!
理解正确,您想在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");
行也没有必要,您可以尝试删除它。