简体   繁体   English

迁移中的实体框架 7 复合键

[英]Entity Framework 7 composite keys in migrations

I'm trying MVC 6, Entity Framework 7 and ASP.NET Identity for the first time.我第一次尝试 MVC 6、Entity Framework 7 和 ASP.NET Identity。 I just generated a default project and I'm changing the login process to support accounts by tenant, based on the following tutorial.我刚刚生成了一个默认项目,我正在根据以下教程更改登录过程以支持租户帐户。

https://www.scottbrady91.com/ASPNET-Identity/Quick-and-Easy-ASPNET-Identity-Multitenancy https://www.scottbrady91.com/ASPNET-Identity/Quick-and-Easy-ASPNET-Identity-Multitenancy

The thing is, when I try to change the initial migration to support a composite key (Id,TenentId) on the AspNetUsers table it simply fails with a generic message.问题是,当我尝试更改初始迁移以支持 AspNetUsers 表上的复合键 (Id,TenentId) 时,它只是失败并显示通用消息。 The migration code is the following.迁移代码如下。

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

I also tried the following code but it also doesn't work.我也尝试了以下代码,但它也不起作用。

constraints: table =>
                    {
                        table.PrimaryKey("PK_ApplicationUser", x => x.Id);     
                        table.PrimaryKey("PK_ApplicationUser", x => x.TenantId);    
                    });

If I leave it as a non composite key the migration executes successfully.如果我将其保留为非复合键,迁移将成功执行。

constraints: table =>
                {
                    table.PrimaryKey("PK_ApplicationUser", x => x.Id);
                });

I tried to define a unique constraint over both columns but I wasn't able to find a way to do it.我试图在两列上定义一个唯一的约束,但我无法找到一种方法来做到这一点。

Does anyone have any thoughts on this?有没有人对此有任何想法?

Any customization of the Identity tables needs to be done by creating derived classes of the Identity model classes and/or by creating a derived class from the IdentityDbContext class. Identity 表的任何自定义都需要通过创建 Identity 模型类的派生类和/或通过从IdentityDbContext类创建派生类来完成。

But I wouldn't try changing the primary key structure of the Identity tables.但我不会尝试更改 Identity 表的主键结构。 I seriously doubt that will work and if it does, there's no gaurantee that it will work properly.我严重怀疑这是否可行,如果确实如此,则无法保证它会正常工作。

Just to get you pointed in the right direction, here's how I modified my IdentityUser class (AspNetUsers table).为了让您指向正确的方向,以下是我修改 IdentityUser 类(AspNetUsers 表)的方法。 I added a few properties to store data I retrieve from Active Directory.我添加了一些属性来存储我从 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; }
}

Doing this requires that you create a derived class from the IdentityDbContext class that uses the model class above.这样做需要您从使用上述模型类的IdentityDbContext类创建派生类。 In mine I rename the Identity tables.在我的中,我重命名了 Identity 表。

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

Then in the ConfigureServices() method in Startup.cs然后在 Startup.cs 的 ConfigureServices() 方法中

//Add Identity services.
services.AddIdentity<ApplicationUser, IdentityRole>()
    .AddEntityFrameworkStores<MyDbContext>()  
    .AddDefaultTokenProviders();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM