EF Core OnDelete restrict添加了额外的列

时间:2017-09-03 02:41:50

标签: entity-framework asp.net-core entity-framework-core

我的模型是多对多的关系:

用户

public class User
{
    public int Id { get; set; }
    public int CompanyId { get; set; }

    [Required]
    [StringLength(100)]
    public string Username { get; set; }

    [Required]
    public string PasswordHash { get; set; }

    [ForeignKey("CompanyId")]
    public Company Company { get; set; }

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

作用

public class Role
{
    public int Id { get; set; }
    public int CompanyId { get; set; }

    [Required]
    [StringLength(100)]
    public string Name { get; set; }

    [StringLength(500)]
    public string Description { get; set; }

    [ForeignKey("CompanyId")]
    public Company Company { get; set; }

    public ICollection<RolePrivilege> RolePrivileges { get; set; }
}

的UserRole

public class UserRole
{
    public int Id { get; set; }
    public int UserId { get; set; }
    public int RoleId { get; set; }

    [ForeignKey("UserId")]
    public User User { get; set; }

    [ForeignKey("RoleId")]
    public Role Role { get; set; }
}

当我创建迁移然后尝试更新数据库时,它会引发多个级联路径的错误。对此的解决方案是使On Delete,No Action所以我在OnModelCreating中添加了这个:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<UserRole>()
            .HasIndex(e => new { e.UserId, e.RoleId })
            .IsUnique();

    modelBuilder.Entity<UserRole>()
        .HasOne(e => e.User)
        .WithMany()
        .OnDelete(DeleteBehavior.Restrict);

    modelBuilder.Entity<UserRole>().ToTable("UserRoles");
}

现在已经创建了表格但是我没想到的一件事就是它创建了一个额外的列。生成后,迁移代码如下所示:

migrationBuilder.CreateTable(
            name: "UserRoles",
            columns: table => new
            {
                Id = table.Column<int>(type: "int", nullable: false)
                    .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
                RoleId = table.Column<int>(type: "int", nullable: false),
                UserId = table.Column<int>(type: "int", nullable: false),
                UserId1 = table.Column<int>(type: "int", nullable: true)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_UserRoles", x => x.Id);
                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.Restrict);
                table.ForeignKey(
                    name: "FK_UserRoles_Users_UserId1",
                    column: x => x.UserId1,
                    principalTable: "Users",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.Restrict);
            });

如您所见,它添加了一个额外的列UserId1。

我做错了什么或如何防止这种情况发生?

1 个答案:

答案 0 :(得分:2)

这是典型关系流畅配置错误的结果 - 使用Has / With的无参数重载(实际上告诉EF没有相应的导航属性),而实际存在导航属性。在这种情况下,EF会将缺少的导航属性映射到另一个关系,另一端没有导航属性,默认为常规FK属性/列名。

要解决此问题,请确保使用表示导航属性存在/不存在的正确重载(并根据您添加/删除导航属性的情况更新它们)。在您的情况下,替换

.WithMany()

.WithMany(e => e.UserRoles)