1

我將嘗試僅將模型的相關部分放在這裏,因爲有相當多的類。希望這足以捕捉問題:EF6代碼首先,多個級聯路徑和奇怪的FK行爲

public class Solve 
{ 
    public int SolveID { get; set; } 

    public int LocationID { get; set; } 
    public virtual Location Location { get; set; } 

    public int ProfileID { get; set; } 
    public virtual Profile Profile { get; set; } 

    public int BillID { get; set; } 
    public virtual Bill Bill { get; set; } 

    public int? PanelID { get; set; } 
    public virtual Panel Panel { get; set; } 
} 

public class Location 
{ 
    public int LocationID { get; set; } 

    [Index] 
    [StringLength(48)] 
    public string Name { get; set; } 

    [Index] 
    public State State { get; set; } 

    public double Latitude { get; set; } 
    public double Longitude { get; set; } 

    public virtual List<Profile> Profiles { get; set; } 
} 

public class Profile 
{ 
    public int ProfileID { get; set; } 

    public int LocationID { get; set; } 
    public virtual Location Location { get; set; } 

    public double Capacity { get; set; } 

    public virtual List<ProfileSample> ProfileSamples { get; set; } 
} 

public class ProfileSample 
{ 
    [Key, ForeignKey("Profile")] 
    [Column(Order = 1)] 
    public int ProfileID { get; set; } 
    public virtual Profile Profile { get; set; } 

    [Key] 
    [Column(Order = 2)] 
    [DataType(DataType.Date)] 
    public DateTime Date { get; set; } 

    [Key] 
    [Column(Order = 3)] 
    public TimeSpan TimeOfDay { get; set; } 

    public double SampleValue { get; set; } 
} 

所以這是所有工作正常,直到我介紹了Solve類,此時它開始抱怨「多階路徑」。我添加了以下上下文,它似乎是確定從那時起:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<Solve>() 
     .HasRequired(s => s.Location) 
     .WithRequiredDependent() 
     .WillCascadeOnDelete(false); 
} 

除了它是不正確行爲:

using (Model.BlueData bd = new Model.BlueData()) 
{ 
    Random rng = new Random(); 

    s = new Model.Solve() 
    { 
     Location = bd.Locations.Find(rng.Next(0, bd.Locations.Count())), 
     Bill  = bd.Bills.Find(rng.Next(0, bd.Bills.Count())), 
     Profile = bd.Profiles.Find(rng.Next(0, bd.Profiles.Count())) 
    }; 

    bd.Solves.Add(s); 
    bd.SaveChanges(); 

    s = bd.Solves 
     .Where(u => u.SolveID == s.SolveID) 
     .Include(u => u.Location) 
     .Include(u => u.Profile) 
     .Include(u => u.Profile.ProfileSamples) 
     .Include(u => u.Bill) 
     .FirstOrDefault(); 
} 

所以上面的代碼只是產生一個隨機Solve對象,將其添加到數據上下文中,然後再次將其與所有關聯的數據一起檢索。這當然有一個更優雅的方式,但現在這只是測試代碼,以確保我的應用程序的其他部分正在工作。

因此如預期,當我創建Solve s對象,s.Location是一個特定的位置,用ID,比方說,1609,當然s.LocationIDs.SolveID的都等於0

將其添加到數據上下文並保存更改後,s.SolveID等於位置的ID(在此示例中爲1609)。這很奇怪。我嘗試在Solve類中添加[Key]屬性到SolveID[ForeignKey("Location")]LocationID,但它沒有區別。

我嘗試了各種方法,如從Solve中刪除Profile或從位置中刪除List<Profile> Profiles。我現在不記得了,但有幾件事情可以糾正設置爲位置ID行爲的s.SolveID

但是,這些屬性都是有原因的,如果可能的話,我寧願不刪除它們只是爲了得到這個工作。我不明白爲什麼會發生這種情況,或者如何正確糾正。我很感激任何幫助。

+0

我認爲,外鍵將需要重新添加,醚作爲數據annotion(你已經tried-,我還以爲是解決方案)或者可能使用流利的API來添加它。這也許可以解決它:http://stackoverflow.com/questions/21229373/ef-foreign-key-using-fluent-api –

回答

2

首先Location被在Solve對象稱爲,所以位置是主要的解決是依賴性的,我認爲在這種情況下,該映射是錯誤 -

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<Solve>() 
     .HasRequired(s => s.Location) 
     .WithRequiredDependent() 
     .WillCascadeOnDelete(false); 
} 

它應該是 -

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<Solve>() 
     .HasRequired(s => s.Location) 
     .WillCascadeOnDelete(false); 
} 

其次,由於Solve引用的外鍵的定義應該是 -

public class Solve 
{ 
    public int SolveID { get; set; } 

    [ForeignKey("Location")] 
    public int LocationID { get; set; } 
    public virtual Location Location { get; set; } 

    [ForeignKey("Profile")] 
    public int ProfileID { get; set; } 
    public virtual Profile Profile { get; set; } 

    [ForeignKey("Bill")] 
    public int BillID { get; set; } 
    public virtual Bill Bill { get; set; } 

    [ForeignKey("Panel")] 
    public int? PanelID { get; set; } 
    public virtual Panel Panel { get; set; } 
} 

第三,保存對象時,必須先保存1)主體,否則EF將嘗試創建新條目或2)必須手動附加它們。其中最容易找到的是(1),在保存主體結束後,我只分配外鍵和EF按預期工作。

using (Model.BlueData bd = new Model.BlueData()) 
{ 
    Random rng = new Random(); 

    s = new Model.Solve() 
    { 
     LocationID = bd.Locations.Find(rng.Next(0, bd.Locations.Count())).LocationID, 
     BillID  = bd.Bills.Find(rng.Next(0, bd.Bills.Count())).BillID, 
     ProfileID = bd.Profiles.Find(rng.Next(0, bd.Profiles.Count())).ProfileID 
    }; 
    s.Bill = s.Location = s.Profile = null; //otherwise EF tries to create them 
    bd.Solves.Add(s); 
    bd.SaveChanges(); 

    s = bd.Solves 
     .Where(u => u.SolveID == s.SolveID) 
     .Include(u => u.Location) 
     .Include(u => u.Profile) 
     .Include(u => u.Profile.ProfileSamples) 
     .Include(u => u.Bill) 
     .FirstOrDefault(); 
} 

編輯1:Location類是 -

public class Location 
{ 
    [Key] //mark location ID as primary key 
    public int LocationID { get; set; } 

    [Index] 
    [StringLength(48)] 
    public string Name { get; set; } 

    [Index] 
    public State State { get; set; } 

    public double Latitude { get; set; } 
    public double Longitude { get; set; } 

    public virtual List<Profile> Profiles { get; set; } 
} 
+0

非常感謝你的答案。這一行:'s.Bill = s.Location = s.Profile = null;',是否有必要?你說否則EF會嘗試創建它們,但它們應該已經是'null'了,對吧? – Ozzah

+0

是的,但這只是爲了確保它們是空的。你不會在任何地方都有相同的代碼。如果它解決了你的問題,請接受答案,以便有相同問題的其他人知道這可能是一個解決方案。 –

+0

我實施了您推薦的更改,現在出現錯誤:Solve_Location_Source :: Multiplicity在「Solve_Location」關係中的'Solve_Location_Source'角色中無效。因爲「依賴角色」屬性不是關鍵屬性,所以「依賴角色」的多重性的上界必須爲「*」。 – Ozzah