Dynamics CRM QueryExpression 嵌套 LinkedEntity
Dynamics CRM QueryExpression nested LinkedEntity
我正在尝试从 Contact
实体检索数据,将其连接到 Function
实体,然后将 Function
连接到 Account
实体。
我们的想法是使用单个查询来检索联系人数据以及来自其他两个的一些额外字段。
我能够加入 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);
这从 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);
}
}
但我无法从嵌套链接实体中获取 entityID
。
AFAIK 别名是正确的,我什至尝试在它前面加上一级链接实体的别名,但没有效果。
谁能指出我正确的方向?
我建议使用工具来代替手动滚动 QueryExpression。
- 下载并安装 XrmToolBox (http://www.xrmtoolbox.com)。
- 从插件商店(在工具菜单上)下载 FetchXml Builder。
- 在图形界面中使用 FetchXml 构建查询。
- 在“查看”菜单上,选择"QueryExpression."
- 右侧会弹出一个 window,显示为您的 FetchXml 查询生成的 QueryExpression。
希望对您有所帮助!
我正在尝试从 Contact
实体检索数据,将其连接到 Function
实体,然后将 Function
连接到 Account
实体。
我们的想法是使用单个查询来检索联系人数据以及来自其他两个的一些额外字段。
我能够加入 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);
这从 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);
}
}
但我无法从嵌套链接实体中获取 entityID
。
AFAIK 别名是正确的,我什至尝试在它前面加上一级链接实体的别名,但没有效果。
谁能指出我正确的方向?
我建议使用工具来代替手动滚动 QueryExpression。
- 下载并安装 XrmToolBox (http://www.xrmtoolbox.com)。
- 从插件商店(在工具菜单上)下载 FetchXml Builder。
- 在图形界面中使用 FetchXml 构建查询。
- 在“查看”菜单上,选择"QueryExpression."
- 右侧会弹出一个 window,显示为您的 FetchXml 查询生成的 QueryExpression。
希望对您有所帮助!