2017-04-12 61 views
0

我正在從ObjectContext將大型項目遷移到DbContext,EF6.1.3。只是遇到一個難以在源代碼中可靠地追蹤實例的問題,並且想知道是否可能有一種方法可以模擬ObjectContext行爲。DbContext vs ObjectContext - 導航屬性行爲更改

考慮兩個類,Parent和Child。父對象具有零個或多個子對象。在表級別,Child具有與Parent對象中的ID列具有FK關係的ParentID列。下面是我生成來說明這個問題兩個POCO類:

Partial Public Class Parent 
    Public Property ID As Integer 

    Public Overridable Property Children As ICollection(Of Child) = New HashSet(Of Child) 

End Class 

Partial Public Class Child 
    Public Property ID As Integer 
    Public Property ParentID As Integer 

    Public Overridable Property Parent As Parent 

End Class 

,這裏是一個小程序來說明這個問題:

Sub Main() 
    Using session As New testEntities 
     Dim parent = session.Parents.Add(session.Parents.Create) 
     Dim child = session.Children.Create 
     parent.Children.Add(child) 
     Console.WriteLine(child.Parent Is Nothing) 
     session.SaveChanges() 
     Console.WriteLine(child.Parent Is Nothing) 
    End Using 

隨着ObjectContext的實現,增加孩子的家長會還設置了孩子的父項屬性。使用DbContext,直到會話被提交後纔會發生這種情況。

在我正在遷移的代碼中有幾個地方(我們迄今爲止已經發現)代碼將被傳遞給已添加到父對象的Child對象的等效對象,然後嘗試引用Parent對象孩子的父項屬性。這些編譯正確,但運行時行爲與DbContext「斷開」。 找到使用這種模式的所有這些實例將代價高昂,並且很容易遺漏將在運行時導致問題的情況。任何人都可以建議一個解決方法,將允許代碼工作嗎?我想我們可以修改TT文件來生成我們自己的類,而不是爲Children屬性使用HashSet,實現一個構造函數,該構造函數接受依賴屬性的引用,以及一個更新相關屬性的Add方法。然而,在我們走下這條路線之前,有沒有更簡單的事情可能導致我們錯過?

+0

我不認爲這是'ObjectContext'或'DbContext'相關,但是實體類(POCO vs special)。你是說你用'ObjectContext'完全相同的實體類嗎? –

+0

這是真的在一定程度上 - 與ObjectContext的導航屬性支持一個EntityCollection類型 - 但與DbContext實體本身被代理包裝,這將給另一個機會做類似的事情 –

+0

哦,不,類,在兩種情況下都是相同的,但它們都是由相關的TT文件生成的 –

回答

1

我不完全確定這會起作用,但我認爲這值得一試。首先,您可以添加家長和孩子之後,嘗試調用此上的DbContext:

ChangeTracker.DetectChanges() 

如果這會導致你想要什麼,只要加叫你也許可以創建自己的DbSet會自動調用這個...即使你必須隱藏Add方法。 (希望只有一個事件可以處理。)

+0

DetectChanges確實有效。儘管如此,我還沒有嘗試將它集成到一個解決方案中,因爲我已經寫了一個HashSet子類的方法 –