2012-05-31 11 views
10

Uso del CRM 2011 SDK (v5.0.10) Tengo un problema con un puñado de campos de búsqueda donde el destino no está ocupado y espero que alguien me ayude a determinar la mejor forma de determinar la entidad a la que se hace referencia en estos casos .En Dynamics 2011 SDK, ¿cómo determinar la entidad objetivo cuando LookupAttributeMetadata.Targets está vacío?

Específicamente, estoy recuperando la Entidad, de atributos y metadatos relación con esta llamada:

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

var entityResponse = (RetrieveAllEntitiesResponse)_organizationService.Execute(entityRequest); 
return entityResponse.EntityMetadata.ToList(); 

Más tarde, mientras se trabaja con un objeto EntityMetadata regresó de esa llamada, inspecciono la colección de atributos y los objetos LookupAttributeMetadata , Intento determinar la entidad a la que hace referencia la búsqueda utilizando la propiedad Targets del objeto LookupAttributeMetadata.

Sin embargo, hay algunos casos en que un objeto LookupAttributeMetadata tiene una colección de objetivos vacía. Por ejemplo, la entidad Actividad de campaña (nombre lógico: campaña activa) tiene el campo Servicio (nombre lógico: servicio) definido como un campo de búsqueda, pero la propiedad Objetivos en el objeto LookupAttributeMetadata está vacía.

VS QuickWatch

Cuando miro a la pantalla personalizaciones de interfaz de usuario web de la entidad y abrir el campo de servicio, en la sección Tipo de muestra es Tipo: búsqueda, registro de objetivo Tipo: Cuenta, Relación Nombre: campaignactivity_account.

Web UI field view

dónde viene esta información?

También tenga en cuenta que no hay relaciones llamadas "campaignactivity_account" en la actividad de la campaña o las entidades de la cuenta.

Actualización: estoy corriendo instalar un depósito de Dynamics CRM 2011 acumulativo de 8 (aunque lo vi en Rolloup 7 también). Si bien la actividad de campaña es el campo que utilicé en mi ejemplo, hay 14 totales con este problema, enumerados a continuación. Estoy buscando una solución general (frente a una solución única para cada uno) para evitar tener un montón de lógica if (entityName=="rollupfield" && fieldName=="organizationid")... en mi código, ya que las entidades y los campos con los que estoy trabajando son seleccionados por el usuario en tiempo de ejecución y yo don No necesariamente sabré por adelantado qué me entregarán.

  • Entidad: acumulativo de Field (rollupfield) Campo: Organización Id (organizationid)
  • Entidad: acumulativo de Query (goalrollupquery) Campo: Ser propietario de usuario (owninguser)
  • Entidad: Proceso de Log (workflowlog) Campo: En cuanto (regardingobjectid)
  • Entidad: Vista guardada (userquery) campo: consulta primaria (parentqueryid)
  • Entidad: Actividad de la campaña (campaignactivity) campo: Servicio (ServiceId)
  • Entidad: Correo electrónico Búsqueda (emailsearch) F ield: Padres (parentobjectid)
  • Entidad: Zona horaria definición (timezonedefinition) Campo: Organización (organizationid)
  • Entidad: respuesta de campaña (campaignresponse) Campo: Servicio (ServiceId)
  • Entidad: Campaña Rápida (bulkoperation) Campo : Servicio (ServiceId)
  • Entidad: permiso campo (fieldpermission) campo: Organización Id (organizationid)
  • Entidad: Nombre de zona horaria localizada (timezonelocalizedname) campo: Organización (organizationid)
  • Entidad: Tiempo regla de zona (timezonerule) Campo: Organización (órgano) izationid)
  • Entidad: Auditoría (auditoría) Campo: Record (objectid)
  • Entidad: Mensaje (post) Campo: RegardingObjectId (regardingobjectid)

Actualización: La siguiente aplicación de consola se puede utilizar para reproducir la cuestión.

//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>"; 
     } 
    } 
} 
+0

Buena pregunta John. No hay respuesta para usted (¿todavía?) Pero observo que en mi implementación de MSCRM 2011, campaignactivity.serviceid es una búsqueda de 'Cita' y tiene un nombre de relación de' campaignactivity_appointment' (que también ** no ** existe).EDITADO: Leí mal lo que estaba en mi sistema 'CampaignActivity_Appointments' existe, pero no es lo mismo, por supuesto) –

+0

También tenga en cuenta: me estoy conectando al servidor usando una cuenta con Modo de acceso = Lectura-Escritura, Tipo de licencia = Completo y miembro de la función Administradores del sistema. –

Respuesta

0

Tengo problemas para entender el problema aquí. Las entidades con un campo de búsqueda pueden tener o no una entidad objetivo. Concedido, he comprobado algunos de estos, pero no se requiere ninguna de las búsquedas de referencia. En el caso de la entidad timezonerule, organizationid siempre es NULL. Sin embargo, basado en su actualización, creo que puede haber llegado a la misma conclusión.

Concedido Uso Fetch en su mayoría, pero tiendo a solo iterar a través de los atributos y en función del tipo de atributo y agregar cada uno en un objeto de diccionario. El objeto del diccionario está envuelto en una lista (es decir, List<Dictionary<string, object>>)

De esta manera puedo simplemente pasar una declaración Fetch genérica y obtener una iList limpia de los atributos poblados. Para las búsquedas, también puede agregar el atributo "_name" para obtener el valor de visualización.

+0

Paul, creo que puede estar hablando de entidades de instancia (es decir, registros en vivo), donde estoy hablando de los metadatos que describen cada entidad. Ciertamente tiene sentido que una búsqueda esté vacía en tiempo de ejecución, pero la definición de esa búsqueda (tiempo de diseño) debería definir la relación, creo. –

1

¿Ha intentado utilizar el mensaje RetrieveRelationshipRequest en su lugar?

que devolverá una clase RetrieveRelationshipResponse, que tiene una propiedad RelationshipMetadata, que a su vez, en función de la relación, que será un ManyToManyRelationshipMetadata OneToManyRelationshipMetadata o. Entre los atributos de la clase OneToManyRelationshipMetadata, encontrará las propiedades ReferencingAttribute y ReferencedAttribute, que es lo que desea.

Cuestiones relacionadas