【发布时间】:2011-12-23 18:13:48
【问题描述】:
所以,手头还有另一个有趣的任务。
我们创建了一个 Windows 服务,以在生产中的 2 个 CRM 2011 组织之间保持一些记录同步。
我们已经研究了我们想要的深度克隆,但它似乎是在深度克隆 EntityReference,而不是实际的 Entity。
任何想法、建议等都会很棒。
【问题讨论】:
标签: c# .net dynamics-crm dynamics-crm-2011
所以,手头还有另一个有趣的任务。
我们创建了一个 Windows 服务,以在生产中的 2 个 CRM 2011 组织之间保持一些记录同步。
我们已经研究了我们想要的深度克隆,但它似乎是在深度克隆 EntityReference,而不是实际的 Entity。
任何想法、建议等都会很棒。
【问题讨论】:
标签: c# .net dynamics-crm dynamics-crm-2011
我已成功使用此代码进行深度克隆:
我使用 XRM 服务上下文,将克隆复制到新实体,删除将其指定为已存在实体的属性(例如主键等)设置与现有实体的关系,然后将其发送到创建方法。我必须对所有相关实体明确地做同样的事情(在我的例子中,我已经为 webfiles 和 notes 做了)
var clonedwebpage = ((Entity)webpage).Clone(true);
clonedwebpage.Id = Guid.NewGuid();
clonedwebpage.Attributes.Remove("adx_webpageid");
//clonedwebpage.Attributes.Remove("adx_pagetemplateid");
clonedwebpage.EntityState = null;
clonedwebpage["adx_websiteid"] = new EntityReference("adx_webpage",livesiteGuid);
//clonedwebpage["adx_parentpageid"] =
// create the template guid
Guid tempGuid = new Guid(templateguid);
clonedwebpage["adx_pagetemplateid"] = new EntityReference("adx_pagetemplate",tempGuid); // set the template of the new clone
//serviceContext.Attach(cloned);
//serviceContext.MergeOption = MergeOption.NoTracking;
Guid clonedwebpageguid = _service.Create(clonedwebpage);
//var webpage = serviceContext.Adx_webpageSet.Where(wp => wp.Id == webpageguid).First();
//var notes_webile = serviceContext.Adx_webfileSet.Where(wf => wf.
//*********************************** WEB FILE *********************************************
foreach (var webfile in webpage.adx_webpage_webfile)
{
var cloned_webfile = webfile.Clone();
//should iterate through every web file that is related to a web page, and clone it.
cloned_webfile.Attributes.Remove("adx_webfileid");
cloned_webfile.Attributes.Remove("adx_websiteid");
cloned_webfile.Attributes.Remove("adx_parentpageid");
cloned_webfile["adx_websiteid"] = new EntityReference("adx_website", livesiteGuid);
cloned_webfile["adx_parentpageid"] = new EntityReference("adx_webpage", clonedwebpageguid);
cloned_webfile.EntityState = null;
cloned_webfile.Id = Guid.NewGuid();
Guid ClonedWebFileGuid = _service.Create(cloned_webfile);
//*********************************** NOTE *********************************************
foreach (var note in webfile.adx_webfile_Annotations)
{
var cloned_note = note.Clone();
cloned_note.Attributes.Remove("annotationid"); // pk of note
cloned_note.Attributes.Remove("objectid"); // set to web file guid
cloned_note["objectid"] = new EntityReference("adx_webfile", ClonedWebFileGuid); // set the relationship between our newly cloned webfile and the note
cloned_note.Id = Guid.NewGuid();
cloned_note.EntityState = null;
Guid clonednote = _service.Create(cloned_note);
//cloned_note.Attributes.Remove("ownerid");
//cloned_note.Attributes.Remove("owningbusinessunit");
//cloned_note.Attributes.Remove("owningteam");
//cloned_note.Attributes.Remove("owninguser");
}
【讨论】:
我们不将其与动态一起使用,但是当我们需要深拷贝时,我们使用 BinaryFormatter 序列化对象,然后将其反序列化为新对象,这与 .Net 远程处理的情况非常相似。
这是我们的 VB.Net 解决方案(如果需要,我可以转换为 C#):
''' <summary>
''' This method clones all of the items and serializable properties of the current collection by
''' serializing the current object to memory, then deserializing it as a new object. This will
''' ensure that all references are cleaned up.
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Function CreateSerializedCopy(Of T)(ByVal oRecordToCopy As T) As T
' Exceptions are handled by the caller
If oRecordToCopy Is Nothing Then
Return Nothing
End If
If Not oRecordToCopy.GetType.IsSerializable Then
Throw New ArgumentException(oRecordToCopy.GetType.ToString & " is not serializable")
End If
Dim oFormatter As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
Using oStream As IO.MemoryStream = New IO.MemoryStream
oFormatter.Serialize(oStream, oRecordToCopy)
oStream.Position = 0
Return DirectCast(oFormatter.Deserialize(oStream), T)
End Using
End Function
【讨论】: