我使用Entity Framework Code First迁移设置了在SQL Server数据库中创建的以下3个类。 调查对象是主表。
public class Survey
{
public int SurveyId {get; set;} //Primary Key
public string Description {get; set;}
public bool HasDevice {get; set;}
public bool HasProcess {get; set;}
public virtual Process Process {get; set;}
public virtual ICollection<Device> Devices {get; set;}
}
每次调查都可以有多个设备(1对多)
public class Device
{
public int DeviceId {get; set;} //Primary Key
public string DeviceType {get; set;}
public int SurveyId {get; set;} //Foreign Key
public virtual Survey Survey {get; set;}
}
每项调查只应有一个流程(1到0..1)
public class Process
{
public int ProcessId {get; set;} //Primary Key
public string ProcessInfo {get; set;}
public int SurveyId {get; set;} //Foreign Key
public virtual Survey Survey {get; set;}
}
这些类的Fluent API映射如下所示。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.HasDefaultSchema("Survey");
modelBuilder.Entity<Survey>().HasOptional(x => x.Process).WithRequired(x => x.Survey);
modelBuilder.Entity<Survey>().HasMany(x => x.Devices).WithRequired(x => x.Survey);
}
问题在于,当我首先应用代码迁移时,Process表中的ForeignKey属性(1到0..1)会一直设置为ProcessId
字段而不是SurveyId
}。这意味着每次我尝试添加新的Process记录时,都会出现以下错误:
INSERT语句与FOREIGN KEY约束“FK_Survey.Processes_Survey.Surveys_ProcessId”冲突。冲突发生在数据库“Backflow”,表“Survey.Surveys”,列“SurveyId”。
Device的1对多映射工作正常。
我最初认为这是因为我的所有PK字段都只是说 Id ,但即使添加了额外的标签部分,它仍会产生错误的PK-FK链接。我也尝试通过添加DataAnnotation [Key, ForeignKey("xyz")]
来避免使用Fluent API,但它具有相同的结果。重新编译项目,重新启动Visual Studio,甚至创建新项目和新数据库都无济于事。
Fluent API或DataAnnotations中是否存在我无法正确连接的内容?此外,手动修复数据库中的FK确实可以使其正常工作,但这种做法违背了使用迁移在Code First中执行所有操作的目的。
答案 0 :(得分:3)
1-0..1关系的流畅映射是正确的:
modelBuilder.Entity<Survey>()
.HasOptional(s => s.Process)
.WithRequired(p => p.Survey);
但是Process
不应该有SurveyID
属性(和列)。在EF6中,1-0..1关系的依赖部分(此处为:Process
)应该具有一个主键,该主键也引用其主体(此处:Survey
)作为外键。所以Process.ProcessID
既是主键,也是外键。因此,一个Process
与Survey
唯一关联。
顺便说一下,在另一个映射中,我还会提到外键:如果选择的配置超过约定,那么最好完成。
modelBuilder.Entity<Survey>()
.HasMany(s => s.Devices)
.WithRequired(d => d.Survey)
.HasForeignKey(d => d.SurveyId);