Search code examples
linq-to-sqlcopyclone

How to do a simple entity copy in Linq-to-SQL?


When using a Linq-to-SQL class, how can I make a simple copy of an entity and save it?

My entity has a guid for a unique ID that gets automatically generated in the SQL Server.

I don't require a "deep clone".

I tried to use some clone methods that are out there but I couldn't figure out how to get everything serialized that needed to be serialized (got stuck on the DataContext not being serializable).

Can I just get an entity, detach it from the DataContext, null out the unique ID and InsertOnSubmit in a new DataContext? If so, how would I do this?

VB.net code preferred but not required.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UPDATE:

Public Shared Function ReIssue(RequestID As Guid) As Guid

    Dim req As Request
    Dim new_req As Request

    Using dc1 As New MBDataContext()
        req = (From r In dc1.Requests Where r.ID = RequestID).Single()
    End Using

    new_req = req
    new_req.ID = Guid.Empty
    new_req.CreateDate = Nothing

    Using dc2 As New MBDataContext()
        dc2.Requests.InsertOnSubmit(new_req)
        dc2.SubmitChanges()
    End Using

End Function

I get an error: An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext. This is not supported.

on this line: dc2.Requests.InsertOnSubmit(new_req)


Solution

  • This method seems to have worked perfectly.

    Making the final code look like this:

    Public Shared Function ReIssue(RequestID As Guid) As Guid
    
        Using dc As New MBDataContext()
            Dim req As Request
            req = (From r In dc.Requests Where r.ID = RequestID).Single()
    
            Dim new_req As Request = DirectCast(Entity.Copy(req, New Request()), Request)
    
            dc.Requests.InsertOnSubmit(new_req)
            dc.SubmitChanges()
    
            req.ActiveRequestParentID = new_req.ID
            dc.SubmitChanges()
    
            Return new_req.ID
        End Using
    
    End Function
    
    Public NotInheritable Class Entity
    
        Private Sub New()
        End Sub
    
        Public Shared Function Copy(source As Object, destination As Object) As Object
            Dim sourceProps As System.Reflection.PropertyInfo() = source.[GetType]().GetProperties()
            Dim destinationProps As System.Reflection.PropertyInfo() = destination.[GetType]().GetProperties()
            For Each sourceProp As System.Reflection.PropertyInfo In sourceProps
                Dim column As ColumnAttribute = TryCast(Attribute.GetCustomAttribute(sourceProp, GetType(ColumnAttribute)), ColumnAttribute)
                If column IsNot Nothing AndAlso Not column.IsPrimaryKey Then
                    For Each destinationProp As System.Reflection.PropertyInfo In destinationProps
                        If sourceProp.Name = destinationProp.Name AndAlso destinationProp.CanWrite Then
                            destinationProp.SetValue(destination, sourceProp.GetValue(source, Nothing), Nothing)
                            Exit For
                        End If
                    Next
                End If
            Next
            Return destination
        End Function
    
    End Class