Используя CRM 2011 SDK (v5.0.10). Я столкнулся с проблемой с несколькими полями поиска, где цель не заполнена, и я надеюсь, что кто-то может помочь мне определить лучший способ определить объект, на который ссылаются, в этих случаях. .
В частности, я получаю метаданные Entity, Attribute и Relationship с помощью этого вызова:
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, я пытаюсь определить объект, на который ссылается поиск, используя свойство Targets объекта LookupAttributeMetadata.
Однако в некоторых случаях объект LookupAttributeMetadata имеет пустую коллекцию Targets. Например, сущность Campaign Activity (логическое имя: campagency) имеет поле Service (логическое имя: serviced), определенное как поле Lookup, но свойство Targets в объекте LookupAttributeMetadata пусто.
Когда я смотрю на экран настроек пользовательского веб-интерфейса для объекта и открываю поле «Сервис», в разделе «Тип» отображается «Тип: Поиск», «Тип целевой записи: Учетная запись», «Имя отношения: кампания_активность_аккаунта».
Откуда эта информация?
Также обратите внимание: нет отношений с именем «campaignactivity_account» ни в объектах Campaign Activity, ни в объектах Account.
Обновление:
Я запускаю стандартную установку Dynamics CRM 2011 Rollup 8 (хотя я видел это и в Rollup 7). Хотя в моем примере я использовал поле «Активность кампании», всего с этой проблемой 14, перечисленных ниже. Я ищу общее решение (по сравнению с одноразовым решением для каждого), чтобы не иметь кучу if (entityName=="rollupfield" && fieldName=="organizationid")...
логика в моем коде, поскольку объекты и поля, с которыми я работаю, выбираются пользователем во время выполнения, и я не обязательно знаю заранее, что мне будет передано.
Обновление: Для воспроизведения проблемы можно использовать следующее консольное приложение.
//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>";
}
}
}