7

我有以下兩種型號及的DbContext:實體框架 - 通過改變更新關係外鍵

public class TestDbContext : DbContext 
    { 
     public IDbSet<Person> People { get; set; } 
     public IDbSet<Car> Cars { get; set; } 
    } 

    public class Person 
    { 
     public Person() 
     { 
      ID = Guid.NewGuid(); 
     } 

     public Guid ID { get; set; } 
     public string Name { get; set; } 
     public virtual List<Car> Cars { get; set; } 
    } 

    public class Car 
    { 
     public Car() 
     { 
      ID = Guid.NewGuid(); 
     } 

     public Guid ID { get; set; } 
     public string Name { get; set; } 
     public virtual Person Owner { get; set; } 
    } 

我再聲明的人的名單和汽車的名單,第一輛車的所有者設置爲第一人名單:

List<Person> People = new List<Person>() 
     { 
      new Person() {Name = "bill", ID = new Guid("6F39CC2B-1A09-4E27-B803-1304AFDB23E3")}, 
      new Person() {Name = "ben", ID = new Guid("3EAE0303-39D9-4FD9-AF39-EC6DC73F630B")} 
     }; 

     List<Car> Cars = new List<Car>() { new Car() { Name = "Ford", Owner = People[0], ID = new Guid("625FAB6B-1D56-4F57-8C98-F9346F1BBBE4") } }; 

我保存這一關,以使用下面的代碼數據庫,並能正常工作。

using (TestDbContext context = new TestDbContext()) 
     { 
      foreach (Person person in People) 
      { 
       if (!(context.People.Any(p => p.ID == person.ID))) 
        context.People.Add(person); 
       else 
       { 
        context.People.Attach(person); 
        context.Entry<Person>(person).State = System.Data.EntityState.Modified; 
       } 
      } 
      foreach (Car caar in Cars) 
      { 
       if (!(context.Cars.Any(c => c.ID == caar.ID))) 
        context.Cars.Add(caar); 
       else 
       { 
        context.Cars.Attach(caar); 
        context.Entry<Car>(caar).State = System.Data.EntityState.Modified; 
       } 
      } 
      context.SaveChanges(); 
     } 

如果我然後將車主更換爲第二人並再次運行代碼,車主屬性不會更新。

Cars[0].Owner = People[1]; 

任何想法,我在做什麼錯?謝謝你的幫助。

+0

剛剛添加,我試圖實現什麼建議http://stackoverflow.com/questions/9382005/move-child-entities-to-a-new-parent-entity – user2697817

+0

你是如何保存它?代碼在哪裏?你需要從DB重新加載'Cars',然後完成任務。 – zsong

回答

2

我認爲這是independent vs foreign key association的問題。您目前正在使用獨立關聯,並且車與人之間的關係實際上是由具有自己狀態的單獨條目對象管理的(要訪問此對象,您必須使用ObjectContext API)。將汽車的實體條目設置爲修改狀態不會改變關係條目的狀態!簡單的解決方案是使用外鍵關聯,這意味着將新的Guid PersonId屬性添加到您的汽車並將其映射爲Person導航屬性的外鍵屬性。

如果您堅持使用獨立關聯,您應該只更改關聯實體之間的關係,否則您將很難跟蹤這些更改並將所有必需條目設置爲正確狀態。創建對象應該足夠了,將它們附加到上下文中,並且在此之後才能設置汽車的所有者 - 希望它可以作爲變化進行跟蹤。

+0

感謝您的幫助,這是類似於做這個答案建議什麼http:// stackoverflow。com/questions/5506116/entity-framework-code-first-why-cant-i-update-complex-properties-this-way – user2697817

+0

是的,它應該是相同的。 –

+0

@LadislavMrnka:請注意:我真的很尊重你,並感謝你在這裏對許多EF問題所做的貢獻......你能否檢查我的問題? http://stackoverflow.com/questions/18529338/entity-framework-controlling-db-connection-and-specifying-own-transaction – Learner

0

嘗試這樣:

using (TestDbContext context = new TestDbContext()) 
      { 
       foreach (Person person in People) 
       { 
        if (!(context.People.Any(p => p.ID == person.ID))) 
         context.People.Add(person); 
        else 
        { 
         context.People.Attach(person); 
         context.Entry<Person>(person).State = System.Data.EntityState.Modified; 
        } 
        context.SaveChanges(); 
       } 
       foreach (Car caar in Cars) 
       { 
        if (!(context.Cars.Any(c => c.ID == caar.ID))) 
         context.Cars.Add(caar); 
        else 
        { 
         context.Cars.Attach(caar); 
         context.Entry<Car>(caar).State = System.Data.EntityState.Modified; 
        } 
        context.SaveChanges(); 
       } 

      } 

,我認爲你的錯誤是由於context.SaveChanges展示位置(和partialy你的架構)。考慮通過實體框架爲數據庫上的每個操作使用專用方法(例如基本的CRUD)。希望這可以幫助。

編輯:有了CRUD計算策略:

public class PersonManager // CRUD 
    { 
     public void Create(Person person) 
     { 
      using (TestDbContext context = new TestDbContext()) 
      { 
       context.Person.Add(person); 
       context.SaveChanges(); 
      } 
     } 

     public void Update(Person person) 
     { 
      using (TestDbContext context = new TestDbContext()) 
      { 
       context.Person.Attach(person); 
       context.Entry(person).State = System.Data.EntityState.Modified; 
       context.SaveChanges(); 
      } 
     } 
    } 

你也可以將這個類static,以適合您的架構。

+0

我試過這種方法,但它仍然無法正常工作。 – user2697817

+0

你剛剛複製/粘貼?或者你創建了一個基本的CRUD?因爲有了CRUD,你不應該有錯誤... – Atlasmaybe

+0

我試過你的建議,它不起作用。也許你需要更清楚。 :-) – user2697817