【问题标题】:Entity Framework 7 composite keys in migrations迁移中的 Entity Framework 7 复合键
【发布时间】:2016-05-11 17:16:56
【问题描述】:

我是第一次尝试 MVC 6、Entity Framework 7 和 ASP.NET Identity。 我刚刚生成了一个默认项目,我正在根据以下教程更改登录过程以支持租户帐户。

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

问题是,当我尝试更改初始迁移以支持 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);     
                        table.PrimaryKey("PK_ApplicationUser", x => x.TenantId);    
                    });

如果我将其保留为非复合键,则迁移将成功执行。

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

我尝试在两列上定义唯一约束,但我无法找到方法。

有人对此有什么想法吗?

【问题讨论】:

  • 你把代码放在哪里了?在 ApplicationUserDbContext 类的 OnModelCreating() 覆盖中?
  • 在初始迁移文件中。

标签: c# asp.net entity-framework asp.net-identity


【解决方案1】:

身份表的任何自定义都需要通过创建身份模型类的派生类和/或从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");
    }
}

然后在 Startup.cs 中的 ConfigureServices() 方法中

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

【讨论】:

  • 感谢分享您如何添加新属性。我同意你关于不改变键结构的观点,改变其他表上的外键会很痛苦。我想我只会在 UserId 之前附加 TenantId,这样我就不会在桌子上重复用户了。
  • 不客气。好的,听起来像一个计划。投赞成票怎么样?我给了你一个。如果您同意更改主键可能不是一个好主意,甚至可以将其标记为已接受的答案。
  • 谢谢。您可以添加 TenantId 字段并在 MyDbContext 类中添加唯一键约束。它可能应该在那里工作。我有一个在其中添加了一些新表并在身份表中添加了与这些表相关的字段。然后为我的新表创建外键约束。
  • 我认为这行不通。由于 UserId 是表键,因此不可能为不同租户拥有同一用户的两条记录。这就是我想要做的。
猜你喜欢
  • 2015-11-07
  • 1970-01-01
  • 2016-05-08
  • 2016-04-12
  • 2015-08-15
  • 2016-09-17
  • 1970-01-01
  • 1970-01-01
  • 2017-10-27
相关资源
最近更新 更多