EF Code First 带有附加外键的多对多
EF Code First Many-to-Many with Additional Foreign Key
我正在使用 Entity Framework Code First 创建一个数据库,其中包含两个实体,如下所示:
public class Tenant {
public Tenant() {
Users = new HashSet<User>();
}
[Key]
public int ID { get; set; }
[Required]
[StringLength(12)]
public string Code { get; set; }
[Required]
[StringLength(200)]
public string Description { get; set; }
public virtual ICollection<User> Users { get; set; }
}
public class User {
public User() {
Tenants = new HashSet<Tenant>();
}
[Key]
public Guid ID { get; set; }
public virtual ICollection<Tenant> Tenants { get; set; }
}
您可以看到我有一个从租户到用户的导航 属性,以及一个从用户到租户的导航 属性。这正确地创建了多对多关系,并导致以下数据库结构:
CREATE TABLE Tenants (
ID INT NOT NULL,
Code NVARCHAR(12) NOT NULL,
Description NVARCHAR(200) NOT NULL
)
CREATE TABLE Users (
ID UNIQUEIDENTIFIER NOT NULL
)
它创建了一个多对多 link table:
CREATE TABLE UserTenants (
User_ID UNIQUEIDENTIFIER NOT NULL,
Tenant_ID INT NOT NULL
)
我的问题是当我尝试向用户实体添加额外的外键字段和导航 属性 时:
public int CurrentTenantID { get; set; }
public virtual Tenant CurrentTenant { get; set; }
我希望这只是向用户添加一个附加字段 table:
CurrentTenantID INT NOT NULL
但是当我为这个新的外键生成迁移时,它做了一些疯狂的事情:
public override void Up()
{
DropForeignKey("acc.UserTenants", "User_ID", "acc.Users");
DropForeignKey("acc.UserTenants", "Tenant_ID", "acc.Tenants");
DropIndex("acc.UserTenants", new[] { "User_ID" });
DropIndex("acc.UserTenants", new[] { "Tenant_ID" });
AddColumn("acc.Tenants", "User_ID", c => c.Guid());
AddColumn("acc.Users", "CurrentTenantID", c => c.Int(nullable: false));
AddColumn("acc.Users", "Tenant_ID", c => c.Int());
CreateIndex("acc.Tenants", "User_ID");
CreateIndex("acc.Users", "CurrentTenantID");
CreateIndex("acc.Users", "Tenant_ID");
AddForeignKey("acc.Users", "CurrentTenantID", "acc.Tenants", "ID", cascadeDelete: true);
AddForeignKey("acc.Tenants", "User_ID", "acc.Users", "ID");
AddForeignKey("acc.Users", "Tenant_ID", "acc.Tenants", "ID");
DropTable("acc.UserTenants");
}
为什么要删除 UserTenants table?它需要做的就是将新列添加到用户table,并创建一个外键约束!
我相信,这是因为 EF 现在需要您提示您要创建哪些关系。
尝试在您的 DbContext 中指定它(覆盖 OnModelCreating):
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<User>().HasMany(b => b.Tenants).WithMany(c => c.Users);
modelBuilder.Entity<User>().HasOptional(b => b.CurrentTenant);
}
我正在使用 Entity Framework Code First 创建一个数据库,其中包含两个实体,如下所示:
public class Tenant {
public Tenant() {
Users = new HashSet<User>();
}
[Key]
public int ID { get; set; }
[Required]
[StringLength(12)]
public string Code { get; set; }
[Required]
[StringLength(200)]
public string Description { get; set; }
public virtual ICollection<User> Users { get; set; }
}
public class User {
public User() {
Tenants = new HashSet<Tenant>();
}
[Key]
public Guid ID { get; set; }
public virtual ICollection<Tenant> Tenants { get; set; }
}
您可以看到我有一个从租户到用户的导航 属性,以及一个从用户到租户的导航 属性。这正确地创建了多对多关系,并导致以下数据库结构:
CREATE TABLE Tenants (
ID INT NOT NULL,
Code NVARCHAR(12) NOT NULL,
Description NVARCHAR(200) NOT NULL
)
CREATE TABLE Users (
ID UNIQUEIDENTIFIER NOT NULL
)
它创建了一个多对多 link table:
CREATE TABLE UserTenants (
User_ID UNIQUEIDENTIFIER NOT NULL,
Tenant_ID INT NOT NULL
)
我的问题是当我尝试向用户实体添加额外的外键字段和导航 属性 时:
public int CurrentTenantID { get; set; }
public virtual Tenant CurrentTenant { get; set; }
我希望这只是向用户添加一个附加字段 table:
CurrentTenantID INT NOT NULL
但是当我为这个新的外键生成迁移时,它做了一些疯狂的事情:
public override void Up()
{
DropForeignKey("acc.UserTenants", "User_ID", "acc.Users");
DropForeignKey("acc.UserTenants", "Tenant_ID", "acc.Tenants");
DropIndex("acc.UserTenants", new[] { "User_ID" });
DropIndex("acc.UserTenants", new[] { "Tenant_ID" });
AddColumn("acc.Tenants", "User_ID", c => c.Guid());
AddColumn("acc.Users", "CurrentTenantID", c => c.Int(nullable: false));
AddColumn("acc.Users", "Tenant_ID", c => c.Int());
CreateIndex("acc.Tenants", "User_ID");
CreateIndex("acc.Users", "CurrentTenantID");
CreateIndex("acc.Users", "Tenant_ID");
AddForeignKey("acc.Users", "CurrentTenantID", "acc.Tenants", "ID", cascadeDelete: true);
AddForeignKey("acc.Tenants", "User_ID", "acc.Users", "ID");
AddForeignKey("acc.Users", "Tenant_ID", "acc.Tenants", "ID");
DropTable("acc.UserTenants");
}
为什么要删除 UserTenants table?它需要做的就是将新列添加到用户table,并创建一个外键约束!
我相信,这是因为 EF 现在需要您提示您要创建哪些关系。 尝试在您的 DbContext 中指定它(覆盖 OnModelCreating):
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<User>().HasMany(b => b.Tenants).WithMany(c => c.Users);
modelBuilder.Entity<User>().HasOptional(b => b.CurrentTenant);
}