C# Dynamics CRM:创建子实体后如何访问父实体元数据?

C# Dynamics CRM:创建子实体后如何访问父实体元数据?,c#,plugins,dynamics-crm,crm,microsoft-dynamics,C#,Plugins,Dynamics Crm,Crm,Microsoft Dynamics,我不仅是C#新手,而且是Microsoft Dynamics新手,我很难通过插件访问联系人的父实体数据。我的目标是在联系人地址字段为空时,用父帐户地址自动填充联系人地址。我觉得这是一个相对简单的过程,我把它复杂化了 public void SetContactAddress() { // TODO: Go and get the contact's parent account record and retrieve the // address fie

我不仅是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);

    }

方法1:(您的方法)

我猜您是在post-create插件上再次显式更新刚创建的联系人。代码也不完整,就像您没有检查空地址字段,不确定分配
联系人[key]=key

方法2:(我推荐)

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

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

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

首先,您应该更改:

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

因为现在您的代码正在将addresss字段的Schemaname指定为值。 你的属性列表是错误的,它们都应该是小写的。SchemaName是camelcase,因此您可以使用:

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

另一种方法是行不通的。地址字段列表过于复杂,更好的方式(对于阅读代码的人来说,更易于维护和理解的方式是:

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
}
var parentContact=parentEntity.ToEntity();
if(isAddressCloned)//如果所有字段都为空,则只应克隆地址,如果所有字段都为空,则不应克隆单个字段
{
contact.Address1_City=parentContact.Address1_City;
contact.Address1\u Country=parentContact.Address1\u Country;
//等
}

正如在其他答案中所述,这应该在预创建联系人时完成,因此联系人应该是您的目标(您的示例代码中没有联系人,但我猜您的插件中有联系人)在这种情况下,您应该跳过最后一次更新。

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

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


我不建议对CRM中的任何内容使用代码优先的方法,因为它需要专业知识来修改。如果您使用工作流,它可以很容易地进行修改;例如,您可能还希望复制业务电话和/或传真号码。

您会遇到什么错误?从业务角度来看,您的逻辑是错误的,因为如果子地址只有第一行和父地址完全不同,并且包含所有三行,您的孩子将有自己的地址和父地址的两行,这是没有意义的。只有当所有字段都为空时,您才应该复制这些字段,否则您会要求系统的数据发生灾难…我以为这是自动完成的a映射?例如,创建您的帐户,设置地址字段(&S)。然后创建此帐户的联系人,并填充地址字段。这仅用于创建,不用于更新。在这种情况下,我将使用工作流,而不是plugin@PawelGradeckiCRM是一种特殊情况,它正日益成为一种功能性环境没有代码可以更好地解决问题
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
}