C# 实体框架7迁移中的组合键

C# 实体框架7迁移中的组合键,c#,asp.net,entity-framework,asp.net-identity,C#,Asp.net,Entity Framework,Asp.net Identity,我第一次尝试MVC6、EntityFramework7和ASP.NETIdentity。 我刚刚生成了一个默认项目,并根据以下教程将登录过程更改为按租户支持帐户 问题是,当我尝试更改初始迁移以支持AspNetUsers表上的复合键(Id,TenentId)时,它只会失败,并显示一条通用消息。 迁移代码如下所示 migrationBuilder.CreateTable( name: "AspNetUsers", columns: t

我第一次尝试MVC6、EntityFramework7和ASP.NETIdentity。 我刚刚生成了一个默认项目,并根据以下教程将登录过程更改为按租户支持帐户

问题是,当我尝试更改初始迁移以支持AspNetUsers表上的复合键(Id,TenentId)时,它只会失败,并显示一条通用消息。 迁移代码如下所示

migrationBuilder.CreateTable(
                name: "AspNetUsers",
                columns: table => new
                {
                    Id = table.Column<string>(nullable: false),
                    TenantId = table.Column<string>(nullable: false),
                    AccessFailedCount = table.Column<int>(nullable: false),
                    ConcurrencyStamp = table.Column<string>(nullable: true),
                    Email = table.Column<string>(nullable: true),
                    EmailConfirmed = table.Column<bool>(nullable: false),
                    LockoutEnabled = table.Column<bool>(nullable: false),
                    LockoutEnd = table.Column<DateTimeOffset>(nullable: true),
                    NormalizedEmail = table.Column<string>(nullable: true),
                    NormalizedUserName = table.Column<string>(nullable: true),
                    PasswordHash = table.Column<string>(nullable: true),
                    PhoneNumber = table.Column<string>(nullable: true),
                    PhoneNumberConfirmed = table.Column<bool>(nullable: false),
                    SecurityStamp = table.Column<string>(nullable: true),
                    TwoFactorEnabled = table.Column<bool>(nullable: false),
                    UserName = table.Column<string>(nullable: true)                    
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_ApplicationUser", x => new { x.Id, x.TenantId });
                });
如果将其保留为非复合密钥,迁移将成功执行

constraints: table =>
                {
                    table.PrimaryKey("PK_ApplicationUser", x => x.Id);
                });
我试图在这两列上定义一个唯一的约束,但我找不到一种方法来实现它


有人对此有什么想法吗?

需要通过创建标识模型类的派生类和/或从
IdentityDbContext
类创建派生类来完成标识表的任何自定义

但我不会尝试更改标识表的主键结构。我严重怀疑这会起作用,如果它真的起作用,就没有高兰蒂认为它能正常工作

为了让您了解正确的方向,下面是我如何修改IdentityUser类(AspNetUsers表)。我添加了一些属性来存储从Active Directory检索的数据

public class ApplicationUser : IdentityUser
{
    [Required]
    [StringLength(50)]
    public string FirstName { get; set; }

    [Required]
    [StringLength(50)]
    public string LastName { get; set; }

    [Required]
    public bool Active { get; set; }
}
执行此操作需要从使用上述模型类的
IdentityDbContext
类创建派生类。在我的中,我重命名了标识表

public class MyDbContext : IdentityDbContext<ApplicationUser>
{
    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        //Rename the ASP.NET Identity tables.
        builder.Entity<ApplicationUser>().ToTable("User");
        builder.Entity<IdentityRole>().ToTable("Role");
        builder.Entity<ApplicationRole>().ToTable("Role");
        builder.Entity<IdentityUserRole<string>>().ToTable("UserRole");
        builder.Entity<IdentityUserLogin<string>>().ToTable("UserLogin");
        builder.Entity<IdentityUserClaim<string>>().ToTable("UserClaim");
        builder.Entity<IdentityRoleClaim<string>>().ToTable("UserRoleClaim");
    }
}
公共类MyDbContext:IdentityDbContext { 模型创建时受保护的覆盖无效(ModelBuilder) { 基于模型创建(生成器); //重命名ASP.NET标识表。 builder.Entity().ToTable(“用户”); builder.Entity().ToTable(“角色”); builder.Entity().ToTable(“角色”); builder.Entity().ToTable(“用户角色”); builder.Entity().ToTable(“UserLogin”); builder.Entity().ToTable(“UserClaim”); builder.Entity().ToTable(“UserRoleClaim”); } } 然后在Startup.cs中的ConfigureServices()方法中

//Add Identity services.
services.AddIdentity<ApplicationUser, IdentityRole>()
    .AddEntityFrameworkStores<MyDbContext>()  
    .AddDefaultTokenProviders();
//添加标识服务。
服务.额外性()
.AddEntityFrameworkStores()
.AddDefaultTokenProviders();

您将代码放在哪里?在初始迁移文件中的ApplicationUserDbContext类的OnModelCreating()重写中。感谢您分享如何添加新属性。在不改变键结构的问题上,我与您意见相左,在其他表上更改外键将是一件痛苦的事情。我想我只需要在UserId之前附加TenantId,这样我就不会有重复的用户了。不客气。好的,听起来像个计划。投赞成票怎么样?我给了你一个。如果您同意更改主键可能不是一个好主意,甚至可以将其标记为已接受的答案。谢谢。您可以添加TenantId字段,并在MyDbContext类中添加唯一的键约束。它应该在那里工作。我在其中添加了一些新表,并在标识表中添加了与这些表相关的字段。然后为我的新表创建了外键约束。我认为这行不通。由于UserId是表键,因此不可能为不同租户拥有同一用户的两条记录。这就是我想做的。
//Add Identity services.
services.AddIdentity<ApplicationUser, IdentityRole>()
    .AddEntityFrameworkStores<MyDbContext>()  
    .AddDefaultTokenProviders();