Dynamics CRM 2011 - фильтрация запросов LINQ с внешними объединениями - PullRequest
2 голосов
/ 13 июня 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,
                   };

Это должно вернуть мне любые сообщения, которые не являются основным контактом учетной записи. Однако этот запрос в итоге возвращает все контакты ...! Когда вы смотрите на SQL, который генерируется в SQL Profiler, он выглядит так:

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

Итак, я получаю левое соединение ОК, но фильтр для предложения 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 ]

7 голосов
/ 13 июня 2011

К сожалению, это ограничение реализации 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 голос
/ 13 июня 2011

Попробуйте это:

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 голосов
/ 01 августа 2013

Если вам не нужно обновлять объект (например, для обработки всех соответствующих правил проверки и шагов рабочего процесса), вы можете писать менее уродливые и более эффективные запросы, напрямую обращаясь к SQL Server.

В соответствии с шаблоном CRM представления позаботятся о большинстве общих объединений для вас.Например, таблицы dbo.ContactBase и dbo.ContactExtensionBase уже объединены для вас в представлении dbo.Contact.AccountName уже существует (по какой-то причудливой причине он называется AccountIdName, но, по крайней мере, он есть).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...