2

我需要在 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,
                   };

这应该向我返回任何不是帐户主要联系人的联系人。但是,此查询最终会返回所有联系人...!当您查看在 SQL Profiler 中生成的 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 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 请求的限制吗?

4

3 回答 3

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/

于 2011-06-13T16:20:43.127 回答
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,
            };
于 2011-06-13T14:19:00.877 回答
0

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

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

于 2013-07-31T20:44:09.330 回答