我正在使用 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