私は EF4.3.1 を使用しており、DBContext を実装しています。
親子関係を持つエンティティがいくつかあります。既存の親を更新するときは、既存の親エンティティを取得し、変更を加えてコンテキストに添付し、変更済みとしてマークして SaveChanges() を呼び出します。
親エンティティに子エンティティがある場合は、同様のプロセスに従います。既存のものを見つけて変更し、変更済みとしてマークします。エンティティのすべての子コレクションをループし、それらをコンテキストに追加またはアタッチする汎用メソッドがありますが、親コレクションになくなったものも削除する必要があります。
たとえば、私の親エンティティがプログラムであり、各プログラムに場所の子コレクションがあるとします。プログラムを最初に挿入すると、3 つの場所があります。後で親を更新すると、場所の数が 2 に減っています。最初の方法では、残りの 2 つの場所を「変更済み」としてマークし、3 つを「未変更」のままにします。
これが私がこれまでに持っている方法ですが、遅いので、より良い方法を望んでいます:
<Extension()>
Public Sub MarkUnmodifiedChildrenAsDeleted(Of T As Class)(context As DbContext, theEntity As T)
'get all of the children navigation properties of the Entity
Dim navigationProperties As List(Of NavigationProperty) = context.GetNavigationProperties(Of T)().Where(Function(w) w.ToEndMember.RelationshipMultiplicity = RelationshipMultiplicity.Many).ToList
'get the
Dim primaryKeyProperty As PropertyInfo = FindPrimaryKeyProperty(context, theEntity)
Dim pkValue As Integer = CInt(primaryKeyProperty.GetValue(theEntity, Nothing))
For Each navigationProperty In navigationProperties
Dim theList = context.Entry(theEntity).Collection(navigationProperty.Name).CurrentValue
If theList.count > 0 Then
'get the foreign key property on the child entity
Dim foreignKeyName As String = DirectCast(navigationProperty.RelationshipType, AssociationType).ReferentialConstraints.Single().ToProperties.Single.Name
'get the child type
Dim propInfo As PropertyInfo = GetType(T).GetProperty(navigationProperty.Name)
Dim propValue As Object = propInfo.GetValue(theEntity, Nothing)
Dim theChildType As Type = propValue.GetType().GetGenericArguments()(0)
'get a dbset that contains all of the Entities that match the Child Type in the database
Dim theDBSet = context.Set(theChildType)
For Each item In theDBSet
Dim dbEE As DbEntityEntry = context.Entry(item)
'if the entity is a child of the current Parent Entity and it's marked as UnChanged, mark it to Deleted
If dbEE.Property(foreignKeyName).CurrentValue = pkValue AndAlso dbEE.State = EntityState.Unchanged Then
dbEE.State = EntityState.Deleted
End If
Next
End If
Next
End Sub