简体   繁体   English

Dynamics CRM QueryExpression 嵌套的 LinkedEntity

[英]Dynamics CRM QueryExpression nested LinkedEntity

I'm trying to retrieve data from the Contact entity, left joining that to Function entity and then joining the Function to an Account entity.我正在尝试从Contact实体中检索数据,将其加入Function实体,然后将Function加入Account实体。

The idea is to use a single query to retrieve contact data plus some extra fields from the other two.这个想法是使用单个查询来检索联系人数据以及其他两个中的一些额外字段。

I'm able to join and retrieve data from a the Function linked entity, but I'm having trouble understanding how to work with nested linked entities.我能够从Function链接实体加入和检索数据,但我无法理解如何使用嵌套链接实体。

QueryExpression queryExpression = new QueryExpression(Contact.EntityLogicalName);

queryExpression.ColumnSet = new ColumnSet(Contact.Fields.pix_GZGId, Contact.Fields.Id, Contact.Fields.FirstName, Contact.Fields.LastName, 
    Contact.Fields.MiddleName, Contact.Fields.GenderCode, Contact.Fields.EMailAddress1, Contact.Fields.EMailAddress2, 
    Contact.Fields.Telephone2, Contact.Fields.MobilePhone, Contact.Fields.pix_Gastlessenoptin);
FilterExpression emailFilter = new FilterExpression(LogicalOperator.Or);

emailFilter.AddCondition(Contact.Fields.EMailAddress1, ConditionOperator.Equal, email);
emailFilter.AddCondition(Contact.Fields.EMailAddress2, ConditionOperator.Equal, email);

FilterExpression nameFilterAll = new FilterExpression(LogicalOperator.And);
nameFilterAll.AddCondition(Contact.Fields.FirstName, ConditionOperator.Equal, firstname);
nameFilterAll.AddCondition(Contact.Fields.LastName, ConditionOperator.Equal, lastname);

if (!String.IsNullOrEmpty(middlename))
{
    nameFilterAll.AddCondition(Contact.Fields.MiddleName, ConditionOperator.Equal, middlename);
}

FilterExpression nameFilterPartial = new FilterExpression(LogicalOperator.And);
nameFilterPartial.AddCondition(Contact.Fields.FirstName, ConditionOperator.BeginsWith, firstname.Substring(0,1));
nameFilterPartial.AddCondition(Contact.Fields.LastName, ConditionOperator.Equal, lastname);

FilterExpression nameFilterLast = new FilterExpression();
nameFilterLast.AddCondition(Contact.Fields.LastName, ConditionOperator.Equal, lastname);

FilterExpression completeNameFilter = new FilterExpression(LogicalOperator.Or);
completeNameFilter.Filters.Add(nameFilterAll);
completeNameFilter.Filters.Add(nameFilterPartial);
completeNameFilter.Filters.Add(nameFilterLast);

queryExpression.Criteria = new FilterExpression(LogicalOperator.And);
queryExpression.Criteria.Filters.Add(emailFilter);
queryExpression.Criteria.Filters.Add(completeNameFilter);

queryExpression.AddOrder(Contact.Fields.LastName, OrderType.Descending);

//this is the problem part - it doesn't seem to do anything.
LinkEntity linkedFunctions = new LinkEntity(Contact.EntityLogicalName, pix_functie.EntityLogicalName, 
    Contact.Fields.Id, pix_functie.Fields.pix_Persoon, JoinOperator.LeftOuter);
linkedFunctions.Columns = new ColumnSet(pix_functie.Fields.Id, pix_functie.Fields.pix_Organisatie, 
    pix_functie.Fields.pix_isgzgfunction, pix_functie.Fields.pix_omschrijving, pix_functie.Fields.CreatedOn);
linkedFunctions.EntityAlias = ConfigKeys.PixFunctieAlias;

FilterExpression accountFilterExpression = new FilterExpression();
//accountFilterExpression.Conditions.Add(new ConditionExpression(pix_functie.Fields.pix_isgzgfunction, ConditionOperator.Equal, true));

linkedFunctions.AddLink(Account.EntityLogicalName, pix_functie.Fields.pix_Organisatie, Account.Fields.Id, JoinOperator.LeftOuter);
linkedFunctions.LinkEntities[0].LinkCriteria = accountFilterExpression;
linkedFunctions.LinkEntities[0].EntityAlias = "linkedAccountAlias";

queryExpression.LinkEntities.Add(linkedFunctions);

request.Query = queryExpression;

RetrieveMultipleResponse response = (RetrieveMultipleResponse)_context.Execute(request);

This gets me data from the Function linked entity no problem, which I then group, order and process:这让我从Function链接实体获取数据没问题,然后我对其进行分组、排序和处理:

    IEnumerable<Microsoft.Xrm.Sdk.Entity> entities = response.EntityCollection.Entities   
            .OrderByDescending(x => (x.GetAttributeValue<AliasedValue>(ConfigKeys.PixFunctieAlias + "." + pix_functie.Fields.pix_isgzgfunction) != null ? (bool?)
                x.GetAttributeValue<AliasedValue>(ConfigKeys.PixFunctieAlias + "." + pix_functie.Fields.pix_isgzgfunction).Value : new Nullable<bool>()).HasValue)
            .ThenByDescending(x => (x.GetAttributeValue<AliasedValue>(ConfigKeys.PixFunctieAlias + "." + pix_functie.Fields.pix_isgzgfunction) != null ? (bool?)
                x.GetAttributeValue<AliasedValue>(ConfigKeys.PixFunctieAlias + "." + pix_functie.Fields.pix_isgzgfunction).Value : null))
            .ThenByDescending(x => (x.GetAttributeValue<AliasedValue>(ConfigKeys.PixFunctieAlias + "." + pix_functie.Fields.CreatedOn) != null ? (DateTime?)
                x.GetAttributeValue<AliasedValue>(ConfigKeys.PixFunctieAlias + "." + pix_functie.Fields.CreatedOn).Value : new Nullable<DateTime>()).HasValue)
            .ThenByDescending(x => (x.GetAttributeValue<AliasedValue>(ConfigKeys.PixFunctieAlias + "." + pix_functie.Fields.CreatedOn) != null ? (DateTime?)
                x.GetAttributeValue<AliasedValue>(ConfigKeys.PixFunctieAlias + "." + pix_functie.Fields.CreatedOn).Value : null));


    List<TtNugGzgDataContract.Entities.Contact> lvl1Contacts = new List<TtNugGzgDataContract.Entities.Contact>();
    List<TtNugGzgDataContract.Entities.Contact> lvl2Contacts = new List<TtNugGzgDataContract.Entities.Contact>();

    foreach(var entity in entities)
    {
        Contact contact = entity.ToEntity<Contact>();
        TtNugGzgDataContract.Entities.Contact contactToAdd = new TtNugGzgDataContract.Entities.Contact()
        {
            externalID = contact.Id,
            firstname = contact.FirstName,
            lastname = contact.LastName,
            insertion = contact.MiddleName,
            gender = Converter.GetApiGender(contact.GenderCodeEnum),
            phone = !String.IsNullOrEmpty(contact.Telephone2) ? contact.Telephone2 : contact.MobilePhone,
            newsletter = contact.pix_GastlessenoptinEnum == pix_nieuwsbriefoptin.Toestaan
        };


        contactToAdd.entityID = entity.GetAttributeValue<AliasedValue>("linkedAccountAlias" + "." + Account.Fields.pix_GZGId) != null ?
            (string)entity.GetAttributeValue<AliasedValue>("linkedAccountAlias" + "." + Account.Fields.pix_GZGId).Value : null;

        contactToAdd.function = entity.GetAttributeValue<AliasedValue>(ConfigKeys.PixFunctieAlias + "." + pix_functie.Fields.pix_omschrijving) != null ?
            (string)entity.GetAttributeValue<AliasedValue>(ConfigKeys.PixFunctieAlias + "." + pix_functie.Fields.pix_omschrijving).Value : null;

        contactToAdd.isGzg = entity.GetAttributeValue<AliasedValue>(ConfigKeys.PixFunctieAlias + "." + pix_functie.Fields.pix_isgzgfunction) != null ?
            (bool?)entity.GetAttributeValue<AliasedValue>(ConfigKeys.PixFunctieAlias + "." + pix_functie.Fields.pix_isgzgfunction).Value : null;

        contactToAdd.createdOn = entity.GetAttributeValue<AliasedValue>(ConfigKeys.PixFunctieAlias + "." + pix_functie.Fields.CreatedOn) != null ?
            (DateTime?)entity.GetAttributeValue<AliasedValue>(ConfigKeys.PixFunctieAlias + "." + pix_functie.Fields.CreatedOn).Value : null;

        EntityReference reference = entity.GetAttributeValue<AliasedValue>(ConfigKeys.PixFunctieAlias + "." + pix_functie.Fields.pix_Organisatie) != null ?
            (EntityReference)entity.GetAttributeValue<AliasedValue>(ConfigKeys.PixFunctieAlias + "." + pix_functie.Fields.pix_Organisatie).Value : null;



        contactToAdd.accId = (entity.GetAttributeValue<AliasedValue>(ConfigKeys.PixFunctieAlias + "." + pix_functie.Fields.pix_Organisatie) != null ?
            (EntityReference)entity.GetAttributeValue<AliasedValue>(ConfigKeys.PixFunctieAlias + "." + pix_functie.Fields.pix_Organisatie).Value : new EntityReference()).Id;


        if (!String.IsNullOrEmpty(contact.EMailAddress1) && contact.EMailAddress1.Equals(email, StringComparison.InvariantCultureIgnoreCase))
        {
            contactToAdd.email = contact.EMailAddress1;
            contactToAdd.isSecondaryEmail = false;
            lvl1Contacts.Add(contactToAdd);
        } else
        {
            contactToAdd.email = contact.EMailAddress2;
            contactToAdd.isSecondaryEmail = true;
            lvl2Contacts.Add(contactToAdd);
        }
    }

But I can't get the entityID out of the nested linked entity.但我无法从嵌套链接实体中获取entityID AFAIK the alias is correct, I've even tried prepending it with the the alias of the first level linked entity to no effect. AFAIK 别名是正确的,我什至尝试在它前面加上第一级链接实体的别名,但没有效果。

Can anybody point me in the right direction?谁能指出我正确的方向?

Rather than hand-rolling your QueryExpression, I suggest using a tool to do it for you. 我建议您不要使用手动滚动QueryExpression的方法来为您完成此任务。

  1. Download and install XrmToolBox ( http://www.xrmtoolbox.com ). 下载并安装XrmToolBox( http://www.xrmtoolbox.com )。
  2. Download the FetchXml Builder from the Plugin Store (on the tools menu). 从插件商店(在工具菜单上)下载FetchXml Builder。
  3. Build your query using FetchXml in the graphical interface. 在图形界面中使用FetchXml构建查询。
  4. On the View menu, choose "QueryExpression." 在视图菜单上,选择“ QueryExpression”。
  5. A window will pop up on the right showing you the generated QueryExpression for your FetchXml query. 右侧将弹出一个窗口,向您显示为FetchXml查询生成的QueryExpression。

Hope that helps! 希望有帮助!

I've been trying different ways of getting attributes off multiple tiers in the "nest" hierarchy.我一直在尝试不同的方法从“嵌套”层次结构中的多个层中获取属性。

Maybe I'm not understanding how FetchXML is supposed to work, when I specify attributes in the parent tables, the child table attribute's don't show.也许我不明白 FetchXML 应该如何工作,当我在父表中指定属性时,子表属性不显示。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM