我有一个类似于以下代码的第一个模型:
public class TestContext : DbContext
{
public DbSet<Class1> Class1s { get; set; }
public DbSet<Class2> Class2s { get; set; }
}
public class Class1
{
public int Class1Id { get; set; }
}
public class Class2
{
public int Class2Id { get; set; }
public int Class1Id { get; set; }
public Class1 Class1 { get; set; }
}
每个Class1对象都有零到多个Class2对象。每个Class2对象必须具有对Class1对象的引用。
我想要做的是从Class1到Class2的可选引用(跟踪与Class1对象关联的Class2对象之一),所以我添加了两个属性:
public class Class1
{
public int Class1Id { get; set; }
public int? Class2Id { get; set; }
public Class2 Class2 { get; set; }
}
现在,当我运行Add-Migration时出现以下错误:
无法确定之间关联的主要结束 类型'ConsoleApplication15.Class2'和'ConsoleApplication15.Class1'。 必须明确配置此关联的主要结尾 使用关系流畅的API或数据注释。
其他StackOverflow答案表明解决方案是在依赖项
上指定外键字段public class Class2
{
[Key, ForeignKey("Class1")]
public int Class2Id { get; set; }
public int Class1Id { get; set; }
public Class1 Class1 { get; set; }
}
我的添加迁移命令现在已完成,但创建的迁移如下:
public override void Up()
{
DropForeignKey("dbo.Class2", "Class1Id", "dbo.Class1");
DropIndex("dbo.Class2", new[] { "Class1Id" });
DropColumn("dbo.Class2", "Class2Id");
RenameColumn(table: "dbo.Class2", name: "Class1Id", newName: "Class2Id");
DropPrimaryKey("dbo.Class2");
AddColumn("dbo.Class1", "Class2Id", c => c.Int());
AlterColumn("dbo.Class2", "Class2Id", c => c.Int(nullable: false));
AddPrimaryKey("dbo.Class2", "Class2Id");
CreateIndex("dbo.Class2", "Class2Id");
AddForeignKey("dbo.Class2", "Class2Id", "dbo.Class1", "Class1Id");
}
这看起来不像我想要的......它正在删除Class2上的主键,它最后添加的外键是完全错误的。
如何描述我对EF的要求,以便生成正确的模型?
答案 0 :(得分:1)
问题是您希望创建one-to-one relationship的惯例EF,如果是这样,您需要指定哪个实体是主体。
如果要在每个实体中创建具有不同PK的一对一关系,则无法在两个实体中声明FK属性。在配置one-to-one relationships时,实体框架要求依赖项的主键也是外键(您在最后一个场景中尝试执行此操作)。
一种解决方案可能是删除FK属性(Class1Id
上的Class2
和Class2Id
上的Class1
)并覆盖上下文中的OnModelCreating
方法以添加这个配置:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Class2>()
.HasRequired(c2 => c2.Class1).
.WithOptional(c1=>c1.Class2);
}
如果您想使用FK属性,可以创建两个单独的关系,如下所示:
modelBuilder.Entity<Class2>()
.HasRequired(s => s.Class1)
.WithMany()
.HasForeignKey(s => s.Class1Id);
modelBuilder.Entity<Class1>()
.HasOptional(s => s.Class2)
.WithMany()
.HasForeignKey(s => s.Class2Id);
我认为最后一个解决方案更适合您尝试实现的方案。