所以,这是另一个有趣的任务。
我们已经创建了一个Windows服务,以便在生产中的2个CRM 2011 orgs之间保持一些记录同步。
我们已经深入研究了我们想要的深度克隆,但它似乎深深地克隆了EntityReference,而不是实际的实体。
任何想法,建议等都会很棒。
答案 0 :(得分:2)
我使用此代码成功深度克隆:
我使用XRM服务上下文,将克隆复制到新实体,删除将其指定为已存在的权限(例如主键等)的属性,建立与现有实体的关系,然后将其发送到创建方法。我必须为所有相关实体明确地做同样的事情(在我的例子中,我为web文件和笔记做了)
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");
}
答案 1 :(得分:1)
我们不使用动态,但是当我们需要深层复制时,我们使用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