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

时间:2011-12-23 18:13:48

标签: c# .net dynamics-crm dynamics-crm-2011

所以,这是另一个有趣的任务。

我们已经创建了一个Windows服务,以便在生产中的2个CRM 2011 orgs之间保持一些记录同步。

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

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

2 个答案:

答案 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