2017-03-09 54 views
0

我使用實體框架代碼第一次遷移設置了要在SQL Server數據庫中創建的以下3個類。 Survey對象是主表。實體框架在代碼第一次遷移時做出不正確的PK-FK映射

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

的問題是,當我申請的代碼第一遷移,在過程表(1到0..1)的ForeignKey的屬性狀態越來越設置爲ProcessId字段而不是SurveyId。這意味着每次我嘗試添加新的過程記錄時,出現以下錯誤:

INSERT語句與FOREIGN KEY約束「FK_Survey.Processes_Survey.Surveys_ProcessId」衝突。衝突發生在數據庫「迴流」,表「Survey.Surveys」,「SurveyId」列中。

設備的一對多映射工作得很好。

最初我以爲這是因爲我所有的PK字段都只是說Id,但即使在添加了額外的標籤部分後,它仍會產生不正確的PK-FK鏈接。我也嘗試通過添加DataAnnotation [Key, ForeignKey("xyz")]來避免Fluent API,但它具有相同的結果。重新編譯項目,重新啓動Visual Studio,甚至創建新項目和新數據庫都無濟於事。

Fluent API或DataAnnotations中是否有某些東西缺少讓它正確連接?此外,手動修復數據庫中的FK確實使其工作,但這種做法違反了Code First中通過遷移完成所有任務的目的。

+0

'過程。當它處於[1:1關係]時,ProcessId'應該是PK和FK(http://stackoverflow.com/a/26425364/861716)。當它是1-0..1。所以你應該刪除'SurveyId'屬性。 –

+0

@Gert好吧,我很困惑。如果將「SurveyId」從Process對象中刪除,那麼它的外鍵是什麼? ProcessID字段是否與調查記錄具有相同的ID? – techturtle

+0

是的,就是這個想法,它獨特地將它與它所屬的「調查」聯繫起來。這也意味着'Process.ProcessId'不是一個標識列。 –

回答

2

的1-0..1關係的流暢映射是正確的:

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

Process不應該有一個SurveyID屬性(列)。在EF6中,1-0..1關係(此處爲:Process)的10從屬部分應該具有主鍵,該主鍵也指其主體(這裏:Survey)作爲外鍵。所以Process.ProcessID是主鍵和外鍵。因此,一個Process與一個Survey唯一聯繫。

順便說一下,在其他映射中,我還會提到外鍵:如果配置選擇超出約定,最好是完整的。

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