Автоматически сгенерированный альтернативный ключ - PullRequest
0 голосов
/ 24 мая 2018

EF Core генерирует альтернативный ключ (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_UserRoles_UserId_RoleId является вопросом, о котором идет речь.Я не хочу, чтобы это было ограничением.Как я могу либо скорректировать свою модель, чтобы соглашения не применяли уникальное ограничение, или что я могу сделать в построителе моделей, чтобы это отрегулировать?

1 Ответ

0 голосов
/ 24 мая 2018

EF Core не генерирует альтернативные ключи автоматически.В данном конкретном случае он генерируется, потому что базовая реализация IdentityDbContext (внутри вызова base.OnModelCreating(builder);) определяет { UserId, RoleId } в качестве первичного ключа для таблицы UserRole.Когда ваш код устанавливает Id в качестве первичного ключа, EF Core не заменяет старый, а вместо этого превращает его в альтернативный ключ.

Нет свободного API для удаления ключей, поэтому вы должны использоватьмодель изменяемых метаданных напрямую.Проще всего удалить старый первичный ключ перед определением нового:

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