【发布时间】:2019-01-23 22:15:56
【问题描述】:
我正在尝试编写一个通用方法,该方法给定任何 Dynamics 365 实体名称和一组 ID (GUIDS),将响应一组与该枚举集匹配的实体记录。我感到沮丧的是,似乎没有一种有效的方法可以让 API 简单地使用“主 ID 密钥”而不首先从元数据中获取它,另一个(似乎不必要的)往返。
考虑以下(被黑)方法:
public EntityCollection HackedFetchEntityRecordsById(IOrganizationService orgSvc, string entityName, IEnumerable<Guid> primaryEntityAttributeIds)
{
// Defacto HACK for getting primary entity attribute
string primaryEntityAttribute = $"{entityName}id";
StringBuilder sb = new StringBuilder();
foreach (Guid guid in primaryEntityAttributeIds)
{
sb.AppendLine($@"<value>{guid}</value>");
}
string fetchXml = $@"
<fetch mapping='logical'>
<entity name='{entityName}'>
<no-attrs />
<filter>
<condition attribute='{primaryEntityAttribute}' operator='in'>
{sb}
</condition>
</filter>
</entity>
</fetch> ";
return orgSvc.RetrieveMultiple(new FetchExpression(fetchXml));
}
请注意,这里我只是使用我观察到的事实标准,因为似乎 Microsoft 已选择使用实体名称后跟字符串“id”来命名实体上的主要 id 属性。这显然是不安全且糟糕的做法。
我可以以“正确”的方式做到这一点,但效率低下:
public EntityCollection InefficientFetchEntityRecordsById(IOrganizationService orgSvc, string entityName, IEnumerable<Guid> primaryEntityAttributeIds)
{
// "Correct" but inefficient way of getting primary entity attribute
string primaryEntityAttribute = ((RetrieveEntityResponse) orgSvc.Execute(new RetrieveEntityRequest
{
LogicalName = entityName
})).EntityMetadata.PrimaryIdAttribute;
StringBuilder sb = new StringBuilder();
foreach (Guid guid in primaryEntityAttributeIds)
{
sb.AppendLine($@"<value>{guid}</value>");
}
string fetchXml = $@"
<fetch mapping='logical'>
<entity name='{entityName}'>
<no-attrs />
<filter>
<condition attribute='{primaryEntityAttribute}' operator='in'>
{sb}
</condition>
</filter>
</entity>
</fetch> ";
return orgSvc.RetrieveMultiple(new FetchExpression(fetchXml));
}
请注意,在这种情况下,我需要进行单独的服务调用(包括所有开销)来获取实体元数据,以便辨别主要属性是什么。呸。
我想做类似以下(幻想/不工作)的方法:
public EntityCollection FantasyFetchEntityRecordsById(IOrganizationService orgSvc, string entityName, IEnumerable<Guid> primaryEntityAttributeIds)
{
StringBuilder sb = new StringBuilder();
foreach (Guid guid in primaryEntityAttributeIds)
{
sb.AppendLine($@"<value>{guid}</value>");
}
// ILLEGAL XML - made up element "primaryEntityAttribute"
string fetchXml = $@"
<fetch mapping='logical'>
<entity name='{entityName}'>
<no-attrs />
<filter>
<primaryEntityAttribute operator='in'>
{sb}
</primaryEntityAttribute>
</filter>
</entity>
</fetch> ";
return orgSvc.RetrieveMultiple(new FetchExpression(fetchXml));
}
我很乐意在 RetrieveMultiple 服务中使用其他一些 QueryBase 实现。
【问题讨论】:
-
“这显然是不安全的,也是一种糟糕的做法。” - 为什么?
-
在下面查看我对您提出的答案的回复!谢谢!
标签: c# dynamics-crm fetchxml dynamics-crm-365