Dynamics CRM中2011 - 过滤LINQ查询与外部连接

问题描述:

我有一个要求在CRM来查询记录中有一定类型的相关实体。通常情况下,我会通过左外连接来完成此操作,然后筛选右侧具有空值的所有行。Dynamics CRM中2011 - 过滤LINQ查询与外部连接

例如:

var query = from c in orgContext.CreateQuery<Contact>() 
      join aj in orgContext.CreateQuery<Account>() 
       on c.ContactId equals aj.PrimaryContactId.Id 
      into wonk 
      from a in wonk.DefaultIfEmpty() 
      where a.Name == null 
      select new Contact 
        { 
         FirstName = c.FirstName, 
         LastName = c.LastName, 
        }; 

这将返回我不是帐户的主要联系人的任何Contats。但是,这个查询结束返回全部联系...!当你看到那个被在SQL事件探查器生成的SQL它出来是这样的:

SELECT cnt.FirstName, cnt.LastName 
FROM Contact as cnt 
    LEFT OUTER JOIN Account AS acct 
     ON cnt.ContactId = acct.PrimaryContactId AND acct.Name is NULL 

所以,我得到的左连接OK,但过滤是Join条款,而不是在一个WHERE并不像它应该这样:

SELECT cnt.FirstName, cnt.LastName 
FROM Contact as cnt 
    LEFT OUTER JOIN Account AS acct 
     ON cnt.ContactId = acct.PrimaryContactId 
WHERE acct.Name is NULL 

显然,这个查询的结果是非常不同的!有没有办法让CRM查询生成正确的SQL?

这是底层FetchXML请求的限制吗?

+0

该表没有“名称”列属于哪一种? – 2011-06-13 14:21:36

+0

@Hassan,Name是账户实体上的一个字段。我只是选择了一个我认为应该总是有这个例子的数据的领域。实际上,我的查询不在内置实体之间。 – Mark 2011-06-13 15:53:47

不幸的是,这是CRM的LINQ和FetchXML实现的限制。这从SDK页面状态外连接不支持:

http://technet.microsoft.com/en-us/library/gg328328.aspx

虽然我不能找到一个正式文件,也有很多成果在那里供人提FetchXML不支持左外连接,例如:

http://gtcrm.wordpress.com/2011/03/24/fetch-xml-reports-for-crm-2011-online/

+0

很奇怪的文档说,这是因为外连接本身的实际工作。从右侧过滤结果是问题。使用原始的FetchXML似乎具有相同的问题。 – Mark 2011-06-13 16:41:43

+0

外连接也适用于我,但我尝试向查询添加连接时遇到了其他问题。 – BrandonG 2013-03-14 22:15:13

+1

我赞成这个答案,因为它看起来是正确的,但同时也是令人失望的。我对CRM的数据访问正在成为过滤视图上LINQ,QueryExpression和ADO.NET查询的混合体,其他人无法正常工作。 ADO.NET查询变得越来越流行,因为QueryExpression对于大型查询变得过于脱节并且难以看到树木,而LINQ(CRM的版本)在其功能方面似乎表现不佳: – 2013-12-02 06:01:01

试试这个:

var query = from c in orgContext.CreateQuery<Contact>() 
      where orgContext.CreateQuery<Account>().All(aj => c.ContactId != aj.PrimaryContactId.Id)     
      select new Contact 
      { 
        FirstName = c.FirstName, 
        LastName = c.LastName, 
      }; 
+0

嗯,但我想过滤a.Name,而不是c.Name? – Mark 2011-06-13 15:54:53

+0

@Mark。检查我更新的答案。希望可以帮助 – 2011-06-13 16:05:36

+0

@Hassan。对不起,这真的不行 - 没有空名称的帐户。在我的示例查询中,“a.Name == null”尝试选择没有匹配帐户的行。 – Mark 2011-06-13 16:23:15

如果没有需要更新的实体(如处理所有相应的验证规则和工作流程步骤),您可以通过点击写丑更小,更高效的查询SQL Server直接。

每CRM的模式,意见照顾最常见的连接为您服务。例如,dbo.ContactBasedbo.ContactExtensionBase表已经在视图dbo.Contact加入了你。 AccountName已经存在(由于某种离奇的原因,称为AccountIdName,但至少在那里)。