C# Dynamics CRM:创建子实体后如何访问父实体元数据?
我不仅是C#新手,而且是Microsoft Dynamics新手,我很难通过插件访问联系人的父实体数据。我的目标是在联系人地址字段为空时,用父帐户地址自动填充联系人地址。我觉得这是一个相对简单的过程,我把它复杂化了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
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
}