2013-01-02 88 views
1

我不明白爲什麼這個配置不會生成一個插入語句到數據庫。我正在通過SQL Profiler進行檢查。實體框架5不會插入自引用多對多的關係

這裏是通過Visio中我的模型:

visiomodel

這裏是我的EDMX(這是數據庫第一)。該圓圈將自我引用關係顯示回GeoBoundary。

edmxmodel

這裏是我的代碼:

public void UpdateAssocs(Dictionary<int, List<int>> fromTo) { 
    //iterate through each dictionary entry 
    foreach (KeyValuePair<int, List<int>> entry in fromTo) { 
    using (TransactionScope scope = new TransactionScope()) { 
     //get a reference to the parent geoboundary for this entry 
     GeoBoundary parent = contactContext.GeoBoundaries 
     .FirstOrDefault(x => x.GeoID == entry.Key); 
     //test to see if the parent is null, it shouldn't be b/c this dictionary was generated 
     // from a list of database values (but shit happens so throw an error if it is null) 
     if (parent != null) { 
     foreach (int childID in entry.Value) { 
      //check to see if the child exists in the parents list of children 
      GeoBoundary child = parent.GeoBoundaryAssocTo 
      .FirstOrDefault(x => x.GeoID == childID); 
      if (child == null) { 
      //get a ref to the GeoBoundary that SHOULD be tied to the parent (it should exist but there just 
      // isn't an established relationship in the db) 
      child = contactContext.GeoBoundaries 
       .FirstOrDefault(x => x.GeoID == childID); 
      //check the damn thing again b/c you never want to assume... 
      // but if it's still null then do nothing! 
      if (child != null) { 
       parent.GeoBoundaryAssocTo.Add(child);     
       contactContext.SaveChanges(); 
      } 
      } 
     } 
     } 
     else { 
     throw new Exception(@"Parent GeoID passed to UpdateAssocs method or GeoID is null."); 
     } 
     scope.Complete(); 
    } 
    } 
} 

當我到parent.GeoBoundaryAssocTo.Add(child);在調試器我確信,父母和孩子都存在,那麼我經歷的一步,但我什麼也得不到的探查。是什麼賦予了?這是一個問題,兩個實體已經存在於數據庫中,我不改變任何東西,但關係?如果是這樣,那麼如何將關係標記爲已更改,以便EF將生成插入?

EDMX詳情:

<AssociationSet Name="GeoBoundaryAssociation" Association="Contact.GeoBoundaryAssociation"> 
     <End Role="GeoBoundary" EntitySet="GeoBoundaries" /> 
     <End Role="GeoBoundary1" EntitySet="GeoBoundaries" /> 
    </AssociationSet> 

    <Association Name="GeoBoundaryAssociation"> 
     <End Type="Contact.GeoBoundary" Role="GeoBoundary" Multiplicity="*" /> 
     <End Type="Contact.GeoBoundary" Role="GeoBoundary1" Multiplicity="*" /> 
    </Association> 
+0

爲什麼要使用TransactionScope? –

+0

@ScottStafford - 如果'Dictionary >'中的內容不正確,我希望整個事情都失敗。 – Chris

+0

當然 - 但無論如何,如果你沒有在ContactContext上使用SaveChanges(),而只是將contactContext移開,它就會這樣做。上下文是一個工作單元 - 當您希望能夠在SaveShanges()之後回滾時,您只需要使用TransactionScope ... –

回答

0

嗯,我是我自己的困境之源。我沒有意識到我正在重新使用我的contactContext(作爲服務類實例化),並且在早期的方法調用中我設置了AutoDetectChangesEnabled = false;。我需要做的就是重新開始更改跟蹤。不知何故,我從來沒有想到,服務類從前面的調用中保持它的狀態。活到老,學到老。

1

你需要確保你的導航屬性附加到當前的DbContext。否則EF將忽略它。

試試這個:

... 

//get a reference to the parent geoboundary for this entry 
GeoBoundary parent = contactContext.GeoBoundaries 
    .include("GeoBoundaryAssocTo") 
    .FirstOrDefault(x => x.GeoID == entry.Key); 

... 
// You may need to use include on your child entity too. 
+0

我試過這個,EF仍然沒有生成插入。 – Chris

+0

您是否嘗試拉動子項目的導航屬性? –

+0

是的,我也試過。我卡住了。 :-) – Chris