【问题标题】:Dynamics CRM: How to access parent entity metadata after creating child?Dynamics CRM:创建子实体后如何访问父实体元数据?
【发布时间】:2017-07-21 20:12:14
【问题描述】:

我不仅是 C# 的新手,而且是 Microsoft Dynamics 的新手,我很难通过插件访问我的联系人的父实体数据。我的目标是使用父帐户地址自动填充我的联系人地址,如果联系人地址字段为空。我觉得这是一个相对简单的过程,我把它复杂化了。

public void SetContactAddress()
    {
        // TODO: Go and get the contact's parent account record and retrieve the 
        // address fields. Then update the contact's address with the fields from the
        // values from the account. Do not overrride the contact's address if one is provided/exists

        var item = _baseModel.TargetEntity as Entity;
        var parent = _baseModel.TargetEntity as Entity;

        Contact contact = new Contact(); //New blank contact in memory
        contact.Id = item.Id; //assign Id to the new local contact

        var service = _targetContact as IOrganizationService;


        Guid parentId = ((EntityReference)contact["new_parentid"]).Id;
        Entity parentEntity = service.Retrieve("new_parent", parentId, new ColumnSet(true)); //retrieve parent entity

        string[] addressAtrributes = {"Address1_City","Address1_Country","Address1_Line1","Address1_Line2",
                 "Address1_Line3", "Address1_PostalCode","Address1_StateOrProvince"};

        foreach (var key in parentEntity.Attributes.Keys)
        {
            if (addressAtrributes.Contains(key))
            {
                //contact.Address1_City = key;
                contact[key] = key;
            }
        }


        //contact.Address1_City = "My City"; //I can easily hard code a city in
            _baseModel.OrganizationService.Update(contact);

    }

【问题讨论】:

  • 你遇到了什么错误?
  • 从业务角度来看,您的逻辑是错误的,因为如果子地址只有第一行而父地址完全不同并且包含所有三行,那么您的孩子将拥有自己的地址和父地址的两行,这将没有意义。仅当所有字段为空时才应复制此字段,否则您将要求系统数据发生灾难...
  • 我以为这是通过映射自动完成的?例如,创建您的帐户并设置地址字段。然后为此帐户创建联系人,并应填充地址字段。这仅适用于创建,不适用于更新。那么在这种情况下,我会使用工作流程,而不是插件

标签: c# plugins dynamics-crm crm microsoft-dynamics


【解决方案1】:

首先,你应该改变:

foreach (var key in parentEntity.Attributes.Keys)
{
    if (addressAtrributes.Contains(key))
    {
        //contact.Address1_City = key;
        contact[key] = key;
    }
}

foreach (var key in parentEntity.Attributes.Keys)
{
    if (addressAtrributes.Contains(key))
    {
        //contact.Address1_City = key;
        contact[key] = parentEntity[key];
    }
}

因为现在您的代码正在将地址字段的 SchemaNames 分配为值。 而且您的属性列表是错误的,它们应该都是小写的。 SchemaName 是驼峰式的,所以你可以使用:

contact.Address1_City //Address1_City is SchemaName, so name of column in DB

contact["address1_city"] //this is name of the field, you can check it in  Customizations area in Dynamics 365

反之则行不通。地址字段列表过于复杂,但更好的方法(对于阅读代码的人来说更易于维护和更容易理解:

var parentContact = parentEntity.ToEntity<Contact>();
if(isAddressCloned) // you should only clone address if all the fields are empty, not cloning single fields if are empty
{
    contact.Address1_City = parentContact.Address1_City;
    contact.Address1_Country = parentContact.Address1_Country;
    //etc
}

如其他答案所述,这应该在 Pre-Create of contact 中完成,因此联系人应该是您的目标(您的示例代码中没有它,但我猜您在插件中的某处有它)和在这种情况下,您应该跳过最后一次更新。

【讨论】:

    【解决方案2】:

    方法 1:(您的方法)

    我猜你是在创建后插件上再次明确更新刚刚创建的联系人。代码也不完整,就像您没有检查空地址字段一样,不确定分配contact[key] = key;

    方法 2:(我推荐的)

    在预创建联系人插件上,您可以检查联系人(目标实体)的地址属性是否为空,然后从检索到的父实体(自定义帐户?)地址字段填充目标实体本身中的这些字段的数据。

    targetEntity.Attributes["Address1_City"] = parentEntity["Address1_City"];
    

    这样可以避免显式更新联系人。

    【讨论】:

      【解决方案3】:

      我的建议是使用工作流程来代替。您可以(免费)获得一些工作流扩展,使您能够为所有关联记录(在本例中为客户的联系人)执行工作流。

      然后只需使用工作流来获取帐户的地址详细信息并覆盖联系人的地址。

      我不建议对 CRM 中的任何内容使用代码优先方法,因为它需要专业知识才能进行修改。如果您使用工作流程,则可以轻松修改它;例如,也许您还想复制公司电话和/或传真号码。

      【讨论】:

      • @PawelGradecki CRM 是一个特例,它正日益成为一种功能性环境,无需代码即可更好地解决问题
      猜你喜欢
      • 2021-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-21
      • 2020-10-22
      • 1970-01-01
      • 1970-01-01
      • 2013-01-19
      相关资源
      最近更新 更多