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 之前创建的。
不久,添加导航 属性 可以更改依赖图顺序,因此 left 和 right 角色在隐式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);
我有两个模型
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 之前创建的。
不久,添加导航 属性 可以更改依赖图顺序,因此 left 和 right 角色在隐式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);