Dynamics crm 2011 Microsoft Dynamics CRM 2011将实体同步到外部数据库表中

Dynamics crm 2011 Microsoft Dynamics CRM 2011将实体同步到外部数据库表中,dynamics-crm-2011,dynamics-crm,crm,Dynamics Crm 2011,Dynamics Crm,Crm,我需要将某些实体(客户、潜在客户、联系人等)同步到crm数据库之外但位于同一服务器上的数据库表。我正在寻找一个支持的方式来做这件事。以下是我尝试过的,但不起作用: 我首先在外部数据库中创建了与dbo.account(视图)中的模式匹配的表。然后我编写了post-create、post-update、post-assign和post-delete插件来创建、更新或删除外部表中的记录(使用ADO.Net)。我以最通用的方式编写了这个插件,这样就可以为任何实体注册它,对插件的更改最少(通过不硬编码字段

我需要将某些实体(客户、潜在客户、联系人等)同步到crm数据库之外但位于同一服务器上的数据库表。我正在寻找一个支持的方式来做这件事。以下是我尝试过的,但不起作用:

我首先在外部数据库中创建了与dbo.account(视图)中的模式匹配的表。然后我编写了post-create、post-update、post-assign和post-delete插件来创建、更新或删除外部表中的记录(使用ADO.Net)。我以最通用的方式编写了这个插件,这样就可以为任何实体注册它,对插件的更改最少(通过不硬编码字段名)。这样做,我遇到的问题是其他表的外键字段。例如,在dbo.account中,有PrimaryContactId和PrimaryContactIdName、PreferredSystemUserId和PreferredSystemUserIdName、ParentAccountId和ParentAccountIdName等字段。在插件的输入参数中,xxxxId字段在更新时可用,但“XXXDName”字段不可用。因此,我无法按原样“同步”表

有没有一个解决方案可以让我的插件解决方案工作? 有没有更好的支持同步表的方法? 提前感谢,

附言:1。数据同步必须是实时的

附言:2。下面是我的函数,用于获取执行更新的查询

私有静态字符串PrepareUpdateQuery(ITracingService tracingService、IEnumerable attributeCollection、字符串entityName、字符串entityIdName)
{
var query=“Update MainDb.MSCRM.”entityName+“set”;
foreach(属性集合中的KeyValuePair KeyValuePair)
{
tracingService.Trace(“Key:{0}”,keyValuePair.Key);
if(keyValuePair.Key!=entityIdName&&keyValuePair.Key!=“modifiedonbehalfby”)
{
query=query+keyValuePair.Key+“=”;
if(keyValuePair.Value==null)
query=query+“null”;
其他的
{
var typeOfValue=keyValuePair.Value.GetType().Name;
tracingService.Trace(“typeOfValue:{0}”,typeOfValue);
开关(类型值)
{
案例“实体参考”:
query=query+“'”+((EntityReference)keyValuePair.Value).Id+“,”;
打破
案例“OptionSetValue”:
query=query+((OptionSetValue)keyValuePair.Value).Value+“,”;
打破
案例“BooleanManagedProperty”:
query=query+((BooleanManagedProperty)keyValuePair.Value).Value?“1”:“0”)+“,”;
打破
违约:
query=query+“'”+keyValuePair.Value+“',”;
打破
}
}
}
}
返回查询;
}

如果您要查找的只是当前正在执行的插件上的属性实体的名称,则EntityReference对象具有一个名称属性,该属性应包含该名称。如果没有,您可以使用id和逻辑名称查询CRM,以获取您在引用实体上查找的任何值

编辑1
如果只是移动数据,为什么还要设置引用的名称呢?我已经从数据库表中删除了这些名称,只是创建了一个查看相应实体名称的视图。这就是CRM正在做的事情。它还使其他数据库更加规范化。例如,如果您更新了被另一个实体引用的实体的名称,您将必须搜索并更新所有这些名称…

xxxIdName字段只是视图的一个助手。实际上,您可以很容易地找出它们是什么 应该包含

例如,假设您拥有一个名为“bob bobson”的主要联系人的帐户“某公司”。 处理帐户实体时,primarycontactId将是guid,primarycontactIdName将是“bob bobson”,accountIdName将是“some company”

在插件中实现这一点的最简单方法是查找相关实体并从中获取值——90%的时间它只是名称字段

您还需要考虑,如果您在使用CRM架构时做了正确的事情,也许最好只复制您需要的字段,并使用自己的模式来同步表。


更新:刚刚看到您的代码,您正在覆盖查询中包含的值,而不是将其设置回基本查询,因此在第二次通过foreach时,您将得到奇怪的结果/错误。如果您死心塌地地地想将相关实体名放在主实体表中,您可以像这样获取它:

var entityEntityRef = (EntityReference)keyValuePair.Value;
var relatedEntity = service.Retrieve(entityRef.LogicalName, entityRef.Id, new ColumnSet(true));

现在relatedEntity作为所有可用属性。大多数情况下,您会查找Name字段,但有些实体是不同的,比如contact,我相信它使用全名字段。

事实上,您可以为所有实体注册一个插件(当然,检查触发消息的插件是否在处理过的插件列表中)

IEnumerable supportees=新字符串[]{“account”,“contact”};
如果(!supportees.Any)(元素
=>元素==targetLogicalName)
返回;
对于链接实体,您有三种选择

  • 跳过它们就行了。不是完全数据同步,但易于实现
  • 仅存储guid。数据同步在实例范围内是有限制的,但相当容易
  • 获取所有链接数据。完整信息,但需要开发递归PIA

  • 谢谢你的回复,达里尔。我做了一个快速测试,看看传递给EntityReference对象的Name属性的是什么,它是空的。即使字段已更新,InputParameter也没有传递给plugi的名称