代码之家  ›  专栏  ›  技术社区  ›  Jeremy Smith

自动生成的备用键

  •  2
  • Jeremy Smith  · 技术社区  · 7 年前

    EF核心正在生成备用密钥( AK_UserRoles_UserId_RoleId )对于以下数据模型:

    数据模型

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

    模型生成器

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

    结果迁移

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

    这个 AK用户角色 以上就是问题所在。我不希望这成为限制。如何调整模型以允许约定不应用唯一约束,或者在模型生成器中如何调整?

    1 回复  |  直到 7 年前
        1
  •  5
  •   Ivan Stoev    7 年前

    EF核心不会自动生成备用密钥。在这种特殊情况下,它的生成是因为 IdentityDbContext 实施(内部 base.OnModelCreating(builder); 呼叫)正在定义 { UserId, RoleId } 作为 UserRole 表。当您的代码设置 Id 作为主键,ef core并没有取代旧的键,而是将其转换为备用键。

    没有用于删除键的Fluent API,因此必须直接使用可变元数据模型。最简单的方法是在定义新的主键之前删除旧的主键:

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