Entity Framework 关系变化时的奇怪迁移

Entity Framework strange migration on relationship change

我有两个模型

  public class Employee
    {
        public Employee()
        {
            Active = true;
        }

        [Key]
        public long Id { get; set; }

        public List<Service> Services { get; set; }

        public List<SubService> SubServices { get; set; }

        [NotMapped]
        public List<long> ServiceIds { get; set; }

        public bool IsSyncedToSP { get; set; }

        public Certificate Certificate { get; set; }

        [NotMapped]
        public List<long> SubServiceIds { get; set; }

        public List<long> GetServiceIds()
        {
            if (ServiceIds != null && ServiceIds.Count > 0)
            {
                return ServiceIds;
            }
            else if (Services != null && Services.Count > 0)
            {
                return Services.Select(s => s.Id).ToList();
            }
            return new List<long>();
        }

public class Certificate
{
    [Key]
    public long Id { get; set; }

    [Required]
    [UnsyncOnEdit(Unsync = true)]
    public string Title { get; set; }

    public bool IsSyncedToSP { get; set; }

    public List<Employee> Employees { get; set; }
}

当我尝试添加 public List<Employee> Employees { get; set; } 这种与证书模型的关系并尝试添加迁移时, EF 创建以下迁移

 public partial class empcert2 : DbMigration
    {
        public override void Up()
        {
            RenameTable(name: "dbo.ServiceClients", newName: "ClientServices");
            RenameTable(name: "dbo.EmployeeServices", newName: "ServiceEmployees");
            DropPrimaryKey("dbo.ClientServices");
            DropPrimaryKey("dbo.ServiceEmployees");
            AddPrimaryKey("dbo.ClientServices", new[] { "Client_Id", "Service_Id" });
            AddPrimaryKey("dbo.ServiceEmployees", new[] { "Service_Id", "Employee_Id" });
        }

        public override void Down()
        {
            DropPrimaryKey("dbo.ServiceEmployees");
            DropPrimaryKey("dbo.ClientServices");
            AddPrimaryKey("dbo.ServiceEmployees", new[] { "Employee_Id", "Service_Id" });
            AddPrimaryKey("dbo.ClientServices", new[] { "Service_Id", "Client_Id" });
            RenameTable(name: "dbo.ServiceEmployees", newName: "EmployeeServices");
            RenameTable(name: "dbo.ClientServices", newName: "ServiceClients");
        }
    }

迁移尝试重命名现有表,当我 运行 它时,它给出 errno:2 没有找到这样的文件错误。

如果我从证书模型中删除 public List<Employee> Employees { get; set; } 这一行,则不会创建奇怪的迁移。

知道为什么会这样

将集合导航 属性 添加到现有关系的主要实体通常不会导致迁移,因为数据库关系是通过从属 table 中的 FK 列定义的。

问题是带有隐式连接 table 的多对多关系的 EF 映射是不确定的。由于涉及的两个 table 在关系中具有相同的角色,哪个被认为是 *left" 或 "right" 完全取决于 EF 模型依赖顺序算法,该算法的唯一要求是确保引用的 table 是在从属 table 之前创建的。

不久,添加导航 属性 可以更改依赖图顺序,因此 leftright 角色在隐式junction table 用于多对多关系。因此,您不应该让 EF 选择它们,并且始终通过 HasMany(左)/WithMany(右)明确指定 API.

要保留您的原始设计,请将以下内容添加到 OnModelCreating 覆盖:

modelBuilder.Entity<Service>().HasMany(e => e.Clients).WithMany(e => e.Services);
modelBuilder.Entity<Employee>().HasMany(e => e.Services).WithMany(e => e.Employees);