Извлеките связанные объекты из каждого, используя RetrieveMultipleRequest

Я пытаюсь получить список объектов из CRM, но я хотел бы получить каждый из них со связанными объектами. До сих пор у меня есть следующий код:

FilterExpression filterExpression = new FilterExpression();
ConditionExpression condition = new ConditionExpression(Constants.ModifiedOnAttribute, ConditionOperator.GreaterEqual, lastSync);
filterExpression.AddCondition(condition);

QueryExpression query = new QueryExpression()
{
     EntityName = entityName,
     ColumnSet = new ColumnSet(attributesMetadata.Select(att => att.Name).ToArray<string>()),
     Criteria = filterExpression,
     Distinct = false,
     NoLock = true
};

RetrieveMultipleRequest multipleRequest = new RetrieveMultipleRequest();
multipleRequest.Query = queryExpression;

RetrieveMultipleResponse response = (RetrieveMultipleResponse)proxy.Execute(multipleRequest);

В ответе переменной я могу увидеть атрибут EntityCollection, но внутри, связанные объекты всегда пусты.

Related entities count is 0

Я хотел бы знать, можно ли получить набор данных сущностей с соответствующими объектами, используя RetrieveMultipleRequest, а не идти один за другим с помощью RetrieveRequest.

Ответ 1

Один подход к возврату связанных данных сущностей - добавление LinkEntities к вашему запросу. Пример ниже даст вам представление о том, как это сделать:

LinkEntity linkEntity = new LinkEntity("email", "new_emails", "activityid", "new_relatedemail", JoinOperator.Inner);
linkEntity.Columns.AddColumn("versionnumber");
linkEntity.Columns.AddColumn("new_emailsid");
linkEntity.EntityAlias = "related";

query = new QueryExpression("email");
query.ColumnSet.AddColumn("activityid");
query.ColumnSet.AddColumn("versionnumber");
query.Criteria.AddCondition("modifiedon", ConditionOperator.NotNull);
query.LinkEntities.Add(linkEntity);

И затем вы можете получить доступ к атрибутам из связанных объектов, используя EntityAlias, указанные выше:

foreach (Entity entity in entities.Entities)
{
    if ((long)(entity["related.versionnumber"] as AliasedValue).Value > 0)
    {
        stop = false;
    }
}

Ответ 2

RetrieveMultipleRequest предназначен для возврата нескольких экземпляров определенного типа объекта. Я провел год, используя CRM SDK из С#, и я не нашел способ заполнить эти связанные сущности в одном запросе. Это в основном оставляет вам два варианта:

  • Используйте параметр AliasedValue, рекомендованный Сергеем. Помните, когда вы запрашиваете 1: Многие отношения, имейте в виду, что вы можете возвращать несколько результатов для одного и того же родительского объекта. Это то, что я использую большую часть времени.

  • Выполните второй запрос для каждой связи, к которой вы хотите получить доступ. Вероятно, вы получите лучшую производительность, если вы можете использовать оператор IN во втором запросе, основываясь на результатах первого, вместо того, чтобы выполнять отдельный запрос для каждого результата первого.

Ниже приведен некоторый псевдокод, чтобы показать разницу.

var contacts = GetContacts();

// One Request to get the cars for the contacts
var cars = GetCarsWhereContactIdIn(contacts.Select( c => c.new_ContactId));

foreach(var c in contacts){
    c.new_Cars.AddRange(cars.where(car => car.new_contactId = c.ContactId));
}

// Verses
var contacts = GetContacts();

foreach(var c in contacts){
    // One Request for each contact
    c.new_Cars.AddRange(GetCarsForContact(c.ContactId));
}