Использование DISTINCT в подзапросе для удаления дубликатов в Entity Framework - PullRequest
1 голос
/ 18 мая 2011

У меня есть вопрос об использовании Distinct с Entity Framework, используя Sql 2005. В этом примере:

practitioners = from p in context.Practitioners
                join pn in context.ProviderNetworks on
                     p.ProviderId equals pn.ProviderId
                (notNetworkIds.Contains(pn.Network))
                select p;

practitioners = practitioners
                  .Distinct()
                  .OrderByDescending(p => p.UpdateDate); 

data = practitioners.Skip(PageSize * (pageOffset ?? 0)).Take(PageSize).ToList();

Все работает нормально, но использование distinct очень неэффективно. Большие наборы результатов приводят к неприемлемой производительности. DISTINCT убивает меня. Различия необходимы только потому, что могут быть запрошены несколько сетей, что приводит к дублированию записей провайдеров. По сути, мне нужно спросить БД «возвращать провайдеров ОДИН РАЗ, даже если они в нескольких сетях». Если бы я мог поместить DISTINCT в сети ProviderNetworks, запрос выполняется намного быстрее.

Как заставить EF добавлять DISTINCT только подзапрос, а не ко всему набору результатов?

Результирующий упрощенный sql, который я НЕ хочу:

select DISTINCT p.* from Providers 
inner join Networks pn on p.ProviderId = pn.ProviderId
where NetworkName in ('abc','def')

IDEAL sql:

select p.* from Providers 
inner join (select DISTINCT ProviderId from Networks 
            where NetworkName in ('abc','def')) 
as pn on p.ProviderId = pn.ProviderId

Спасибо Dave

1 Ответ

6 голосов
/ 18 мая 2011

Я не думаю, что вам нужно Distinct здесь, но Exists (или Any, как его называют в Linq)

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

    var q = (from p in context.Practitioners
            where context.ProviderNetworks.Any(pn => pn.ProviderId == p.ProviderId && notNetworkIds.Contains(pn.Network))
            orderby p.UpdateDate descending
            select p).Skip(PageSize * (pageOffset ?? 0)).Take(PageSize).ToList();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...