【问题标题】:How to clone a record (server side) in Dynamics crm 2016?如何在 Dynamics crm 2016 中克隆记录(服务器端)?
【发布时间】:2018-10-05 17:08:34
【问题描述】:

我正在使用 crm 2016,我需要使用插件克隆记录,谷歌搜索后我发现我需要使用 Microsoft.Xrm.Client 来保存 clone() 函数 - 它不在2016 SDK 因为 MS 重组。这个库在 2015 SDK。
我的问题是:
1. 如果我从 CRM 2015 中获取该库并在 2016 年使用它,它会被支持吗?
2. 如果不支持,我有哪些选择可以在服务器端克隆记录?

【问题讨论】:

    标签: dynamics-crm dynamics-crm-2016 cloning


    【解决方案1】:

    微软公告称:

    我们还从 CRM 2016 (8.x) SDK 客户端中删除了 Microsoft.Xrm.Client,因为它不符合 OAuth 更改,并将其替换为 Microsoft.Xrm.Tooling.Connector。您可以使用当前的 Microsoft Dynamics 365 软件开发工具包 (SDK) 将 Microsoft Dynamics CRM 访问回版本 6.x 以进行身份​​验证和消息传递。

    Dynamics 365 SDK Backwards Compatibility

    您仍然可以在旧 SDK 的项目中使用 Microsoft.Xrm.Client.dll,这可能会支持一段时间。

    但我建议使用自定义操作,将父记录作为 EntityReference 输入参数,检索父记录数据 + 所需的相关实体并在操作中手动创建(克隆)子记录 + 相关实体记录。

    您可以从客户端/服务器端执行/调用此Action,无论您想要什么。

    【讨论】:

      【解决方案2】:

      Microsoft.Xrm.Client 中的方法Clone() 仅在内存中创建Entity 对象的副本。它不会在 CRM 的数据库中创建副本。当您需要在数据库中创建副本时,只需实例化一个新的Entity 对象并将其传递给IOrganizationService 接口的Create() 方法即可。

      当您确实需要如MSDN 中所述的深度克隆时,您可以考虑自己编写一个。在大多数情况下,您只需要复制属性集合中的对象。在这些对象中,只有 EntityReferenceOptionSetValueMoney 的引用类型需要您特别注意。

      我不建议使用已弃用的库。

      【讨论】:

        【解决方案3】:

        我们使用以下帮助方法来克隆实体 - 这是原始版本的更新版本,它正确克隆了引用类型,并排除了系统属性

        public static Entity CloneEntitySandbox(Entity entityToClone)
            {
                var newEntity = new Entity(entityToClone.LogicalName);
        
                var systemAttributes = new List<string>();
                systemAttributes.Add("createdon");
                systemAttributes.Add("createdby");
                systemAttributes.Add("modifiedon");
                systemAttributes.Add("modifiedby");
                systemAttributes.Add("owninguser");
                systemAttributes.Add("owningbusinessunit");
        
        
                foreach (var attribute in entityToClone.Attributes
                    .Where(x => x.Key != entityToClone.LogicalName + "id")
                    .Where(x => !systemAttributes.Contains(x.Key))) 
                {
        
                    switch (attribute.Value.GetType().Name)
                    {
                        case "Money":
                            var m = attribute.Value as Money;
                            newEntity[attribute.Key] = new Money(m.Value);
                            break;
                        case "EntityReference":
                            var er = attribute.Value as EntityReference;
                            newEntity[attribute.Key] = new EntityReference(er.LogicalName, er.Id);
                            break;
                        case "OptionSetValue":
                            var os = attribute.Value as OptionSetValue;
                            newEntity[attribute.Key] = new OptionSetValue(os.Value);
                            break;
                        default:
                            newEntity[attribute.Key] = attribute.Value;
                            break;
                    }
        
                }
        
                return newEntity;
            }
        

        请注意,这不会执行保存以在 CRM 数据库中创建克隆实体,这取决于您。

        【讨论】:

        • 在您的示例中,引用类型 EntityReferenceOptionSetValueMoney 未被克隆。仅复制对这些对象的引用。
        • @HenkvanBoeijen 诚然,是的,引用类型的字段最终会指向原始实体上的值 - 但是,当克隆的实体保存到数据库时,您最终会得到一个新的副本预期的原始实体
        • 当克隆的实体被保存两次到数据库时,你最终会得到原始实体的两个新副本,大声笑!
        • 为什么不在attributesrcEntity.Attributes 的每个属性的循环中执行newEntity.Attributes.Add(attribute)
        • @DonCheadle 因为这样你的原始实体和克隆实体都引用了相同的属性 - 更改属性的值将有效地更改两个实体的值。
        猜你喜欢
        • 2016-09-10
        • 1970-01-01
        • 1970-01-01
        • 2018-03-01
        • 1970-01-01
        • 2014-01-31
        • 2022-06-14
        • 2023-03-13
        • 2022-01-21
        相关资源
        最近更新 更多