当使用Linq-to-SQL类时,我如何制作一个实体的简单副本并保存它?
我的实体有一个在SQL Server中自动生成的唯一ID的guid。
我不需要"深度克隆"。
我试着使用一些克隆方法,但我不知道如何让所有需要序列化的东西序列化(卡在DataContext
不可序列化上)。
我可以得到一个实体,从DataContext
中分离出来,在新的DataContext
中清空唯一的ID和InsertOnSubmit
吗?如果有,我该怎么做?
VB.net代码优先,但不是必需的。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
更新:
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
我得到一个错误:尝试附加或添加一个不是新的实体,可能已经从另一个DataContext加载。这是不支持的。
这一行:dc2.Requests.InsertOnSubmit(new_req)
清空唯一id,然后调用InsertOnSubmit
是正确的方法。有些事情你必须考虑:
- id的类型是什么?是
int
吗?AGuid
?它是空的吗?如果它是可空的,请确保将其设置为空,如果它是int
,则为0,或者Guid
,则为Guid.Empty
。 - 类型是否有某种时间戳?如果是,那么你必须根据类型将其重置/设置为null。
一旦你这样做了,你可以调用InsertOnSubmit
,然后SubmitChanges
,改变应该发生。
注意,如果您要对大量记录执行此操作,您最好编写一个存储过程,该存储过程将使用从另一个表中选择的方法执行插入到表中。这种方式将快得多(您不会将数据从数据库加载到内存中,然后将其推回,每次插入一条记录)。
这个方法似乎效果很好。
使最终代码看起来像这样: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