实体框架:尝试深度克隆对象时出错

时间:2015-04-11 19:19:57

标签: vb.net entity-framework

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

0 个答案:

没有答案