Dynamics CRM 2011 - 使用外部联接筛选LINQ查询

时间:2011-06-13 14:08:59

标签: linq dynamics-crm dynamics-crm-2011

我需要在CRM中查询具有某种类型的相关实体的记录。通常,我会使用左外连接执行此操作,然后筛选右侧有NULL的所有行。

例如:

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

所以,我得到了Left Join,但过滤器是 on 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请求的限制吗?

3 个答案:

答案 0 :(得分:7)

不幸的是,这是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/

答案 1 :(得分:1)

试试这个:

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,
            };

答案 2 :(得分:0)

如果您不需要更新实体(例如,处理所有相应的验证规则和工作流程步骤),您可以通过直接访问SQL Server来编写不那么丑陋且更有效的查询。

根据CRM的模式,视图会为您处理大多数常见联接。例如,dbo.ContactBasedbo.ContactExtensionBase表已在视图dbo.Contact中为您加入。 AccountName已经存在(出于某些奇怪的原因称为AccountIdName,但至少它存在)。