使用 CRM 2011 SDK (v5.0.10) 我遇到了一些查找字段的问题,其中没有填充目标,我希望有人可以帮助我确定在这些情况下确定引用实体的最佳方法。
具体来说,我正在使用此调用检索实体、属性和关系元数据:
var entityRequest = new RetrieveAllEntitiesRequest
{
RetrieveAsIfPublished = true,
EntityFilters = EntityFilters.Entity | EntityFilters.Attributes | EntityFilters.Relationships
};
var entityResponse = (RetrieveAllEntitiesResponse)_organizationService.Execute(entityRequest);
return entityResponse.EntityMetadata.ToList();
稍后,在处理从该调用返回的 EntityMetadata 对象时,我检查了 Attributes 集合,对于 LookupAttributeMetadata 对象,我尝试使用 LookupAttributeMetadata 对象的 Targets 属性来确定查找所引用的实体。
但是,在某些情况下 LookupAttributeMetadata 对象有一个空的 Targets 集合。例如,Campaign Activity(逻辑名称:campaignactivity)实体将 Service 字段(逻辑名称:serviced)定义为 Lookup 字段,但 LookupAttributeMetadata 对象的 Targets 属性为空。
当我查看实体的 Web UI 自定义屏幕并打开服务字段时,在类型部分下显示类型:查找,目标记录类型:帐户,关系名称:campaignactivity_account。
这些信息来自哪里?
另请注意:活动活动或帐户实体上没有名为“campaignactivity_account”的关系。
更新:我正在运行 Dynamics CRM 2011 Rollup 8 的库存安装(尽管我在 Rolloup 7 上也看到了这一点)。虽然活动活动是我在示例中使用的字段,但此问题共有 14 个,如下所列。我正在寻找一个通用解决方案(每个解决方案都是一次性解决方案)来避免if (entityName=="rollupfield" && fieldName=="organizationid")...
在我的代码中包含一堆逻辑,因为我正在使用的实体和字段是由用户在运行时选择的,而我没有不一定提前知道我会得到什么。
- 实体:汇总字段(rollupfield) 字段:组织ID(organizationid)
- 实体:汇总查询(goalrollupquery) 字段:拥有用户(owninguser)
- 实体:流程日志(workflowlog) 字段:关于(关于objectid)
- 实体:已保存视图 (userquery) 字段:父查询 (parentqueryid)
- 实体:活动活动(campaignactivity) 字段:服务(serviceid)
- 实体:电子邮件搜索 (emailsearch) 字段:父 (parentobjectid)
- 实体:时区定义(timezonedefinition) 字段:组织(organizationid)
- 实体:活动响应(campaignresponse) 字段:服务(serviceid)
- 实体:快速活动(批量操作) 字段:服务(serviceid)
- 实体:字段权限(fieldpermission) 字段:组织ID(organizationid)
- 实体:时区本地化名称(timezonelocalizedname) 字段:组织(organizationid)
- 实体:时区规则(timezonerule) 字段:组织(organizationid)
- 实体:审计(audit) 字段:记录(objectid)
- 实体:帖子(post) 字段:关于ObjectId(关于objectid)
更新:以下控制台应用程序可用于重现该问题。
//Requires the following Referenses:
// Microsoft.CSharp
// Microsoft.IdentityModel
// Microsoft.xrm.sdk
// System
// System.Core
// System.Data
// System.Runtime.Serialization
// System.ServiceModel
using System;
using System.Linq;
using System.Net;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Metadata;
namespace TargetlessLookupsPOC
{
internal static class Program
{
private const string OrganizationServiceURL =
"http://dynamicscrm1/DynamicsCRM1/XRMServices/2011/Organization.svc";
private static void Main(string[] args)
{
Console.WriteLine("====== Authenticating ");
var organizationServiceMngt =
ServiceConfigurationFactory.CreateManagement<IOrganizationService>(new Uri(OrganizationServiceURL));
var authCred = new AuthenticationCredentials();
authCred.ClientCredentials.Windows.ClientCredential = new NetworkCredential();
IOrganizationService orgProxy = new OrganizationServiceProxy(organizationServiceMngt,
authCred.ClientCredentials);
Console.WriteLine("====== Fetching All Entity Metadata ");
var entityRequest = new RetrieveAllEntitiesRequest
{
RetrieveAsIfPublished = true,
EntityFilters = EntityFilters.Entity | EntityFilters.Attributes | EntityFilters.Relationships
};
var entityResponse = (RetrieveAllEntitiesResponse) orgProxy.Execute(entityRequest);
Console.WriteLine("====== Searching For Targetless Lookups ");
foreach (var ent in entityResponse.EntityMetadata)
{
foreach (var field in ent.Attributes
.OfType<LookupAttributeMetadata>()
.Where(lookup => !lookup.Targets.Any()))
{
Console.WriteLine("Entity: {0} ({1}), Field: {2} ({3}) (type: {4}) is targetless",
ent.DisplayName.LabelText(), ent.LogicalName,
field.DisplayName.LabelText(), field.LogicalName,
field.AttributeType);
}
}
Console.WriteLine("=========================== Done");
Console.WriteLine("** Press any key to continue **");
Console.ReadKey();
}
public static string LabelText(this Label label)
{
return (label != null && label.UserLocalizedLabel != null)
? label.UserLocalizedLabel.Label
: "<no label>";
}
}
}