在Dynamics 2011 SDK中,如何在LookupAttributeMetadata.Targets为空时确定目标实体?

Joh*_*ght 10 c# dynamics-crm dynamics-crm-2011

使用CRM 2011 SDK(v5.0.10)我遇到了少数Lookup字段的问题,其中目标没有填充,我希望有人可以帮助我确定在这些情况下确定引用实体的最佳方法.

具体来说,我正在使用此调用检索实体,属性和关系元数据:

var entityRequest = new RetrieveAllEntitiesRequest
                        {
                           RetrieveAsIfPublished = true,
                           EntityFilters = EntityFilters.Entity | EntityFilters.Attributes | EntityFilters.Relationships
                           };

var entityResponse = (RetrieveAllEntitiesResponse)_organizationService.Execute(entityRequest);
return entityResponse.EntityMetadata.ToList();
Run Code Online (Sandbox Code Playgroud)

稍后,在使用从该调用返回的EntityMetadata对象时,我检查Attributes集合,对于LookupAttributeMetadata对象,我尝试使用LookupAttributeMetadata对象的Targets属性确定查找引用的实体.

但是,在某些情况下,LookupAttributeMetadata对象具有空的Targets集合.例如,Campaign活动(逻辑名称:campaignactivity)实体将Service字段(逻辑名称:serviced)定义为Lookup字段,但LookupAttributeMetadata对象上的Targets属性为空.

VS QuickWatch

当我查看实体的Web UI Customizations屏幕并打开Service字段时,在Type部分下显示Type:Lookup,Target Record Type:Account,Relationship Name:campaignactivity_account.

Web UI字段视图

这些信息来自哪里?

另请注意:Campaign活动或帐户实体上没有名为"campaignactivity_account"的关系.

更新:我正在运行Dynamics CRM 2011 Rollup 8的库存安装(尽管我在Rolloup 7上也看到了这一点).虽然"广告系列活动"是我在我的示例中使用的字段,但总共有14个问题,如下所示.我正在寻找一个通用的解决方案(针对每个解决方案的一次性解决方案),以避免if (entityName=="rollupfield" && fieldName=="organizationid")...在我的代码中使用一堆逻辑,因为我正在使用的实体和字段是由用户在运行时选择的,我不知道我必须提前知道我会被交给谁.

  • 实体:汇总字段(汇总字段)字段:组织标识(organizationid)
  • 实体:汇总查询(goalrollupquery)字段:拥有用户(拥有者)
  • 实体:流程日志(workflowlog)字段:关于(aboutobjectid)
  • 实体:已保存的视图(userquery)字段:父查询(parentqueryid)
  • 实体:Campaign活动(campaignactivity)字段:服务(serviceid)
  • 实体:电子邮件搜索(emailsearch)字段:父母(parentobjectid)
  • 实体:时区定义(timezonedefinition)字段:组织(organizationid)
  • 实体:广告系列响应(campaignresponse)字段:服务(serviceid)
  • 实体:快速广告系列(bulkoperation)字段:服务(serviceid)
  • 实体:字段权限(fieldpermission)字段:组织ID(organizationid)
  • 实体:时区本地化名称(timezonelocalizedname)字段:组织(organizationid)
  • 实体:时区规则(timezonerule)字段:组织(organizationid)
  • 实体:审计(审计)字段:记录(目标)
  • 实体:帖子(帖子)字段:AboutObjectId(aboutobjectid)

更新:以下控制台应用程序可用于重现该问题.

//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>";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Pau*_*Way 0

我很难理解这里的问题。具有查找字段的实体可能有也可能没有目标实体。当然,我抽查了其中一些,但不需要任何引用的查找。对于 timezonerule 实体,organizationid 始终为 NULL。不过,根据您的更新,我认为您可能得出了相同的结论。

当然,我主要使用 Fetch,但我倾向于只迭代属性并基于属性类型,并将每个属性添加到 Dictionary 对象中。字典对象被包装在一个列表中(即 List<Dictionary<string, object>>

这样我就可以传递一个通用的 Fetch 语句并返回一个干净的已填充属性的 iList。对于查找,您还可以附加“_name”属性来获取显示值。