简体   繁体   English

自动生成的备用密钥

[英]Auto-generated Alternate Key

EF Core is generating an Alternate Key ( AK_UserRoles_UserId_RoleId ) for the following data model: EF Core正在为以下数据模型生成备用密钥( AK_UserRoles_UserId_RoleId ):

Data Model 资料模型

 public class User : IdentityUser<Guid>
{
    [MaxLength(50)]
    public String FirstName { get; set; }

    [MaxLength(50)]
    public String LastName { get; set; }

    public virtual ICollection<UserRole> UserRoles { get; set; }
}

public class Role : IdentityRole<Guid>
{
    public string Description { get; set; }

    public virtual ICollection<UserGroupToRole> UserGroups { get; set; }
}


public class UserRole : IdentityUserRole<Guid>
{
    public Guid Id { get; set; }

    public virtual User User { get; set; }

    public virtual Role Role { get; set; }

    public int? EntityId { get; set; }

    public string EntityType { get; set; }
}

Model Builder 模型制作者

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        builder.Entity<User>(i =>
        {
            i.ToTable("Users");
            i.HasKey(x => x.Id);
            i.Property(u => u.Id).HasDefaultValueSql("NEWID()");

            i.HasMany(u => u.UserRoles)
                .WithOne(ur => ur.User)
                .HasForeignKey(ur => ur.UserId)
                .IsRequired();
        });

        builder.Entity<Role>(i =>
        {
            i.ToTable("Roles");
            i.HasKey(x => x.Id);
            i.Property(u => u.Id).HasDefaultValueSql("NEWID()");
            i.HasMany(x => x.UserGroups);

            i.HasMany<UserRole>()
                .WithOne(ur => ur.Role)
                .HasForeignKey(ur => ur.RoleId)
                .IsRequired();
        });

        builder.Entity<UserRole>(i =>
        {
            i.ToTable("UserRoles");
            i.HasKey(x => x.Id);
            i.Property(x => x.Id).HasDefaultValueSql("NEWID()");
            i.HasIndex(x => new { x.UserId, x.RoleId, x.EntityId, x.EntityType }).IsUnique();
        });

    }

Resulting Migration 结果迁移

 migrationBuilder.CreateTable(
            name: "UserRoles",
            columns: table => new
            {
                Id = table.Column<Guid>(nullable: false, defaultValueSql: "NEWID()"),
                EntityId = table.Column<int>(nullable: true),
                EntityType = table.Column<string>(nullable: false),
                RoleId = table.Column<Guid>(nullable: false),
                UserId = table.Column<Guid>(nullable: false)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_UserRoles", x => x.Id);
                table.UniqueConstraint("AK_UserRoles_UserId_RoleId", x => new { x.UserId, x.RoleId });
                table.ForeignKey(
                    name: "FK_UserRoles_Roles_RoleId",
                    column: x => x.RoleId,
                    principalTable: "Roles",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.Cascade);
                table.ForeignKey(
                    name: "FK_UserRoles_Users_UserId",
                    column: x => x.UserId,
                    principalTable: "Users",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.Cascade);
            });

The AK_UserRoles_UserId_RoleId above is what is in question. 上面的AK_UserRoles_UserId_RoleId是有问题的。 I do not wish for this to be a constraint. 我不希望这成为约束。 How can I either adjust my model to allow the conventions to not apply the Unique Constraint or what can I do in the Model Builder to adjust this? 如何调整模型以允许约定不应用唯一约束,或者如何在模型构建器中进行调整呢?

EF Core is not automatically generating alternate keys. EF Core不会自动生成备用密钥。 In this particular case it's generated because the base IdentityDbContext implementation (inside base.OnModelCreating(builder); call) is defining { UserId, RoleId } as a primary key for the UserRole table. 在此特定情况下,由于基础IdentityDbContext实现(在base.OnModelCreating(builder);调用内部)将{ UserId, RoleId }定义为UserRole表的主键,因此生成了该表。 When your code sets the Id as a primary key, EF Core is not replacing the old one, but instead turns it into alternate key. 当您的代码将Id设置为主键时,EF Core不会替换旧的Id ,而是将其转换为备用键。

There is no fluent API for removing keys, so you have to use the mutable metadata model directly. 没有有效的API来删除密钥,因此您必须直接使用可变元数据模型。 The easiest is to remove the old primary key before defining the new one: 最简单的方法是在定义新主键之前删除旧主键:

builder.Entity<UserRole>(i =>
{
    i.Metadata.RemoveKey(i.Metadata.FindPrimaryKey().Properties);
    // ...
});

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

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