2012-05-31 12 views
10

Utilizzo dell'SDK CRM 2011 (v5.0.10) Sto riscontrando un problema con una manciata di campi di ricerca in cui la destinazione non è popolata e spero che qualcuno possa aiutarmi a determinare il modo migliore per determinare l'entità referenziata in questi casi .In Dynamics 2011 SDK, come determinare l'entità di destinazione quando LookupAttributeMetadata.Targets è vuoto?

In particolare, sto recuperando l'Entità, attributi e metadati rapporto con questo invito:

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

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

Più tardi, mentre si lavora con un oggetto EntityMetadata tornato da quella chiamata, ho ispezionare la collezione Attributi e per gli oggetti LookupAttributeMetadata , Cerco di determinare l'entità a cui fa riferimento la ricerca utilizzando la proprietà Targets dell'oggetto LookupAttributeMetadata.

Tuttavia, vi sono alcuni casi in cui un oggetto LookupAttributeMetadata ha una raccolta di destinazioni vuota. Ad esempio, l'entità Attività campagna (nome logico: campagna) ha il campo Servizio (nome logico: servito) definito come un campo di ricerca, ma la proprietà Targets sull'oggetto LookupAttributeMetadata è vuota.

VS QuickWatch

Quando guardo lo schermo personalizzazioni dell'interfaccia utente web per l'entità e aprire il campo di servizio, sotto la sezione tipo viene spettacoli Tipo: Ricerca, Target Record Type: account, Nome di relazione: campaignactivity_account.

Web UI field view

Da dove provengono queste informazioni?

Nota: non ci sono relazioni denominate "campaignactivity_account" nelle attività della campagna o nelle entità account.

Aggiornamento: Sto eseguendo un'installazione stock di Dynamics CRM 2011 Rollup 8 (anche se l'ho visto su Rolloup 7). Mentre Attività campagna è il campo che ho usato nel mio esempio, ci sono 14 totali con questo problema, elencati di seguito. Sto cercando una soluzione generale (contro una soluzione una tantum per ciascuno) per evitare di avere un po 'di logica if (entityName=="rollupfield" && fieldName=="organizationid")... nel mio codice, dal momento che le entità e i campi con cui sto lavorando sono selezionati dall'utente in fase di runtime e io 'necessariamente sapere in anticipo cosa riceverò.

  • Entity: Rollup Field (rollupfield) Campo: Organizzazione Id (organizationid)
  • Entity: Rollup Query (goalrollupquery) Campo: Possedere utente (owninguser)
  • Entity: processo di log (workflowlog) Campo: Per quanto riguarda (regardingobjectid)
  • Entity: vista salvata (UserQuery) campo: Parent Query (parentqueryid)
  • Entità: attività della campagna (campaignactivity) campo: servizi (service_id)
  • Entità: E-mail Search (emailsearch) F ield: Parent (parentobjectid)
  • Entity: Time Zone Definizione (timezonedefinition) Campo: Organizzazione (organizationid)
  • Entity: Response Campaign (campaignresponse) Campo: servizi (service_id)
  • Entity: mini-campagna (bulkoperation) Campo : servizi (service_id)
  • Entity: autorizzazione Field (fieldpermission) campo: Organizzazione Id (organizationid)
  • Entity: Time Zone Localized Nome (timezonelocalizedname) campo: Organizzazione (organizationid)
  • Entity: Time Zone Regola (timezonerule) Settore: Organizzazione (organo izationid)
  • Entity: Auditing (audit) Campo: Record (ObjectID)
  • Entity: Post (post) Campo: RegardingObjectId (regardingobjectid)

Update: Il seguente console applicazione può essere utilizzato per riprodurre il problema.

//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

Buona domanda John. Nessuna risposta per te (ancora?) Ma noto che nella mia distribuzione MSCRM 2011, campaignactivity.serviceid è una ricerca di "Appuntamento" e ha un nome di relazione di "campaignactivity_appointment" (che anche ** non ** esiste).MODIFICATO: ho interpretato erroneamente ciò che era nel mio sistema 'CampaignActivity_Appointments' esiste ma non è lo stesso ovviamente) –

+0

Nota: sto connettendo al server utilizzando un account con Modalità di accesso = Read-Write, Tipo di licenza = Completo e un membro del ruolo degli amministratori di sistema. –

risposta

0

Ho problemi a comprendere il problema qui. Le entità con un campo di ricerca possono avere o meno un'entità di destinazione. Concesso che ho controllato alcuni di questi spot, ma non era richiesta alcuna delle ricerche referenziate. Nel caso dell'entità timezonerule, l'ID di organizzazione è sempre NULL. Basandomi sul tuo aggiornamento, penso che potresti essere giunto alla stessa conclusione.

Concesso Uso la raccolta per lo più, ma tendo solo a scorrere gli attributi e in base al tipo di attributo e aggiungere ciascuno in un oggetto dizionario. L'oggetto dizionario è racchiuso in un elenco (List<Dictionary<string, object>>)

In questo modo posso solo passare un'istruzione Fetch generica e ottenere un elenco pulito degli attributi popolati. Per le ricerche, è anche possibile aggiungere l'attributo "_name" per ottenere il valore visualizzato.

+0

Paul, penso che potresti parlare di entità di istanza (es .: registrazioni dal vivo), dove sto parlando dei metadati che descrivono ogni entità. Ha certamente senso che una ricerca sia vuota in fase di esecuzione, ma credo che la definizione di tale ricerca (design-time) debba definire la relazione. –

1

Hai provato a utilizzare il messaggio RetrieveRelationshipRequest?

Ciò restituirà una classe RetrieveRelationshipResponse, che ha una proprietà RelationshipMetadata, che a sua volta, a seconda della relazione, sarà un OneToManyRelationshipMetadata o ManyToManyRelationshipMetadata. Tra gli attributi della classe OneToManyRelationshipMetadata, troverai le proprietà ReferencingAttribute e ReferencedAttribute, che è ciò che desideri.

Problemi correlati