尝试使用OR查询某些相关实体和AND查询其他相关实体

时间:2014-02-14 16:26:05

标签: dynamics-crm-2011

我在创建查询时遇到一些困难,我在某些相关的实体字段和其他相关的实体字段上使用Or。我正在使用QueryExpression,因为这是我最熟悉的,但如果有更好的方法,我会全力以赴。

具体来说,我正在查询合同,其中BillTo.Name或Customer.Name等于传入值,并且相关合同行上的某些自定义值等于传入值。这是我到目前为止所尝试的。问题是它使用And运算符而不是Or来处理BillTo名称和客户名称。

QueryExpression qe = new QueryExpression(Contract.EntityLogicalName);

ColumnSet acctColumns = new ColumnSet("name");
LinkEntity acctlink = new LinkEntity("contract", "account", "customerid", "accountid", JoinOperator.Inner);
acctlink.LinkCriteria.FilterOperator = LogicalOperator.Or;
acctlink.LinkCriteria.AddCondition("name", ConditionOperator.Equal, CustName);
acctlink.Columns = acctColumns;
qe.LinkEntities.Add(acctlink);

ColumnSet billToColumns = new ColumnSet("name");
LinkEntity billToLink = new LinkEntity("contract", "account", "billingcustomerid", "accountid", JoinOperator.Inner);
billToLink.LinkCriteria.FilterOperator = LogicalOperator.Or;
billToLink.LinkCriteria.AddCondition("name", ConditionOperator.Equal, CustName);
billToLink.Columns = billToColumns;
qe.LinkEntities.Add(billToLink);

ColumnSet contractColumns = new ColumnSet("expireson");
LinkEntity contractLineLink = new LinkEntity("contract", "contractdetail", "contractid", "contractid", JoinOperator.Inner);
contractLineLink.Columns = contractColumns;

LinkEntity productLink = new LinkEntity("contractdetail", "product", "productid", "productid", JoinOperator.Inner);
productLink.LinkCriteria.AddCondition("productnumber", ConditionOperator.Equal, ProductID);
contractLineLink.LinkEntities.Add(productLink);

qe.LinkEntities.Add(contractLineLink);

FilterExpression fe = new FilterExpression(LogicalOperator.And);
ConditionExpression ceVersion = new ConditionExpression("new_version", ConditionOperator.Equal, versionID);
ConditionExpression ceCust = new ConditionExpression("new_cust", ConditionOperator.Equal, true);
ConditionExpression ceComp = new ConditionExpression("new_comp", ConditionOperator.Like, formattedDBName);

fe.AddCondition(ceVersion);
fe.AddCondition(ceCust);
fe.AddCondition(ceComp);

qe.Criteria.AddFilter(fe);
qe.ColumnSet = cs;

EntityCollection contractDetails = crmService.RetrieveMultiple(qe);

编辑 - 最终代码 这是我在阅读了达林提到的选项后最终做的事情。

        Guid acctGuid = acctRef.Id; //  Retrieve EntityReference in another method
        ColumnSet cs = new ColumnSet();

        QueryExpression qe = new QueryExpression(Contract.EntityLogicalName);

        ColumnSet contractColumns = new ColumnSet("expireson", "new_registrationkey");
        LinkEntity contractLineLink = new LinkEntity("contract", "contractdetail", "contractid", "contractid", JoinOperator.Inner);
        contractLineLink.Columns = contractColumns;

        LinkEntity productLink = new LinkEntity("contractdetail", "product", "productid", "productid", JoinOperator.Inner);
        productLink.LinkCriteria.AddCondition("productnumber", ConditionOperator.Equal, ProductID);
        contractLineLink.LinkEntities.Add(productLink);

        qe.LinkEntities.Add(contractLineLink);

        FilterExpression fe = new FilterExpression(LogicalOperator.And);
        ConditionExpression ceVersion = new ConditionExpression("new_version", ConditionOperator.Equal, VersionID);
        ConditionExpression ceCust = new ConditionExpression("new_cust", ConditionOperator.Equal, true);
        ConditionExpression ceComp = new ConditionExpression("new_comp", ConditionOperator.Like, formattedName);
        fe.AddCondition(ceVersion);
        fe.AddCondition(ceCust);
        fe.AddCondition(ceComp);

        qe.Criteria.AddFilter(fe);
        qe.ColumnSet = cs;

        FilterExpression fe2 = new FilterExpression(LogicalOperator.Or);
        ConditionExpression ceCustomerName = new ConditionExpression("customerid", ConditionOperator.Equal, acctGuid);
        ConditionExpression ceBillToName = new ConditionExpression("billingcustomerid", ConditionOperator.Equal, acctGuid);
        fe2.AddCondition(ceCustomerName);
        fe2.AddCondition(ceBillToName);
        qe.Criteria.AddFilter(fe2);

        EntityCollection contractDetails = crmService.RetrieveMultiple(qe);

1 个答案:

答案 0 :(得分:2)

你有两个选择

  1. 将您的InnerJoin更改为LeftOuter,然后在客户端过滤结果。

  2. 执行两个单独的查询,一个用于客户ID的内部联接,另一个用于结算客户ID的内部联接,然后在客户端进行组合。

  3. FilterOperator = LogicalOperator.Or仅适用于过滤器中的ConditionExpression,因为您只设置了一个ConditionExpression,它实际上并没有做任何事情。