从一个组织到另一个组织的深度克隆实体

本文关键字:深度 实体 另一个 一个 | 更新日期: 2023-09-27 18:18:38

那么,又一个有趣的任务来了。

我们已经创建了一个windows服务来保持生产中的两个CRM 2011组织之间的一些记录同步。

我们已经研究了我们想要的深度克隆,但它似乎是对EntityReference的深度克隆,而不是实际的实体。

任何想法,建议等都会很棒。

从一个组织到另一个组织的深度克隆实体

我用下面的代码成功地进行了深度克隆:

我使用XRM服务上下文,将克隆复制到一个新实体,删除将其指定为已经存在的实体的属性(例如主键等),建立与现有实体的关系,然后将其发送给create方法。我必须明确地为所有相关实体做同样的事情(我已经为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