Entity Framework 在 Code First 迁移中进行不正确的 PK-FK 映射

Entity Framework making incorrect PK-FK mapping on Code First migration

我将以下 3 类 设置为使用 Entity Framework Code First 迁移在 SQL 服务器数据库中创建。 调查对象是主要的table。

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;} 
}

每个调查可以有多个设备(一对多)

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);
}

问题是,当我应用代码第一次迁移时,进程 table (1-to-0..1) 中的 ForeignKey 属性 一直设置为 ProcessId 字段而不是 SurveyId。这意味着每次我尝试添加新的 Process 记录时,我都会收到以下错误:

INSERT 语句与 FOREIGN KEY 约束冲突 "FK_Survey.Processes_Survey.Surveys_ProcessId"。冲突发生在数据库 "Backflow"、table "Survey.Surveys"、列 'SurveyId'。

设备的一对多映射工作得很好。

我最初认为这是由于我所有的 PK 字段都只写 Id,但即使添加了附加标签部分,它仍然使 PK-FK 不正确link。我也尝试通过添加 DataAnnotation [Key, ForeignKey("xyz")] 来避免 Fluent API,但结果相同。重新编译项目,重新启动 Visual Studio,甚至创建新项目和新数据库都无济于事。

我在 Fluent API 或 DataAnnotations 中是否缺少某些内容以使其正确加入?此外,手动修复数据库中的 FK 确实可以正常工作 ,但这种做法违背了在 Code First 中通过迁移完成所有操作的目的。

1-0..1关系的流畅映射是正确的:

modelBuilder.Entity<Survey>()
    .HasOptional(s => s.Process)
    .WithRequired(p => p.Survey);

但是 Process 不应该有 SurveyID 属性(和列)。在 EF6 中,1-0..1 关系的 dependent 部分(此处:Process)应该有一个主键,该主键也引用其 principal(此处:Survey)作为外键。所以 Process.ProcessID 既是主键又是外键。因此,一个 Process 唯一地绑定到一个 Survey.

顺便说一句,在其他映射中,我还要提到外键:如果选择配置而不是约定,最好是完整的。

modelBuilder.Entity<Survey>()
    .HasMany(s => s.Devices)
    .WithRequired(d => d.Survey)
    .HasForeignKey(d => d.SurveyId);