我正在使用Entity Framework 6,数据库优先。使用现有Sql server数据库中的向导创建模型。 我正在使用此代码进行深度克隆:
Imports System.ComponentModel
Imports System.Collections
Imports System.Data.Entity.Core.Objects.DataClasses
Imports System.Runtime.Serialization
Imports System.IO
Imports System.Reflection
Imports System.Runtime.CompilerServices
Module Extensions
Private Function ClearEntityObject(Of T As Class)(ByVal source As T, ByVal bCheckHierarchy As Boolean) As T
If (source Is Nothing) Then
Throw New Exception("Null Object cannot be cloned")
End If
Dim tObj As Type = source.GetType
If (Not tObj.GetProperty("EntityKey") Is Nothing) Then
tObj.GetProperty("EntityKey").SetValue(source, Nothing, Nothing)
End If
If bCheckHierarchy Then
Dim PropertyList As List(Of PropertyInfo) = Enumerable.ToList(Of PropertyInfo)((From a In source.GetType.GetProperties
Where a.PropertyType.Name.Equals("ENTITYCOLLECTION`1", StringComparison.OrdinalIgnoreCase)
Select a))
Dim prop As PropertyInfo
For Each prop In PropertyList
Dim keys As IEnumerable = DirectCast(tObj.GetProperty(prop.Name).GetValue(source, Nothing), IEnumerable)
Dim key As Object
For Each key In keys
Dim childProp As EntityReference = Enumerable.SingleOrDefault(Of PropertyInfo)((From a In key.GetType.GetProperties
Where (a.PropertyType.Name.Equals("EntityReference`1", StringComparison.OrdinalIgnoreCase))
Select a)).GetValue(key, Nothing)
ClearEntityObject(childProp, False)
ClearEntityObject(key, True)
Next
Next
End If
Return source
End Function
<Extension()> _
Public Function ClearEntityReference(ByVal source As Object, ByVal bCheckHierarchy As Boolean) As Object
Return ClearEntityObject(source, bCheckHierarchy)
End Function
<Extension()> _
Public Function Clone(Of T)(ByVal source As T) As T
Dim ser As New DataContractSerializer(GetType(T))
Using stream As MemoryStream = New MemoryStream
ser.WriteObject(stream, source)
stream.Seek(0, SeekOrigin.Begin)
Return DirectCast(ser.ReadObject(stream), T)
End Using
End Function
End module
现在,我尝试使用这样的代码:
Private Sub DoClone
Dim litm, newitm As MyObject
litm = context.MyObjects.FirstOrDefault
newitm = litm.Clone()
newitm.ClearEntityReference(True)
context.MyObjects.Add(newitm)
context.SaveChanges()
End Sub
我收到错误:
未处理的类型异常 发生'System.Runtime.Serialization.SerializationException' System.Runtime.Serialization.dll
其他信息:输入 'System.Data.Entity.DynamicProxies.MyObject_F2FFE64DA472EB2B2BDF7E143DE887D3845AD9D1731FD3107937062AC0C2E4BB' 与数据合同名称 'MyObject_F2FFE64DA472EB2B2BDF7E143DE887D3845AD9D1731FD3107937062AC0C2E4BB:http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies' 不是预期的。
考虑使用DataContractResolver或添加任何 静态地知道已知类型列表的类型 - 例如, 通过使用KnownTypeAttribute属性或将它们添加到 传递给DataContractSerializer的已知类型列表。
这是我使用的模型:
Partial Public Class Myobject
Public Property id As Integer
Public property name as string
Public Overridable Property chld As ICollection(Of chld) = New HashSet(Of chld)
Public Overridable Property chld1 As ICollection(Of chld1) = New HashSet(Of chld1)
End Class
Partial Public Class chld
Public Property id As Integer
Public Property date1 as DateTime
Public Property quantity as Integer
Public Property ParentID as integer
Public Overridable Property MyObj1 As MyObject
End Class
Partial Public Class chld1
Public Property id As Integer
Public Property nm as string
Public Property ParentID as integer
Public Overridable Property MyObj1 As MyObject
End Class