ПОЛНОЕ НАРУЖНОЕ СОЕДИНЕНИЕ на основе «многие ко многим» с помощью LINQ Entity Framework - PullRequest
0 голосов
/ 24 января 2012

У меня есть отношение "многие ко многим" продуктов (p) и материалов (m) и таблицы products2materials (p2m) в качестве ссылки "многие ко многим".

Мне нужно получить

- all products that have materials assigned,
- all products with no materials assigned,
- and all materials with no products assigned.

В основном объединение того, что есть.Однако, поскольку это будет фильтр данных, мне нужно отфильтровать товары и / или материалы, которые не соответствуют критериям поиска (например, все товары, начинающиеся с "A" и т. Д.).

Как мне сделать это в LINQ-to-EF 4.1?

Большое спасибо!

Ответы [ 3 ]

1 голос
/ 12 ноября 2013

Следующее должно делать работу:

from m in context.Materials //m has to be the first
from p in context.Products    
where !p.Select(p1 => p1.Material).Contains(m) || p.Material == null || p.Material == m

Для производительности, вероятно, было бы лучше следующее:

var a = from p in context.Products select p.Material;

var b = from m in context.Materials //m has to be the first
        from p in context.Products    
        where a.Contains(m) || p.Material == null || p.Material == m 
0 голосов
/ 24 января 2012

По вашему описанию это выглядит так, как будто вам действительно нужно:

  1. Все продукты
  2. Все неиспользованные материалы

Вам это нужно как один IQueryable(если да, какие поля вам нужны) или как 2 IQueryables?

0 голосов
/ 24 января 2012

Linq не предлагает полную операцию внешнего соединения напрямую, поэтому ваш лучший выбор - попробовать разделить запросы L2E слева и справа на отдельные и объединить их в один набор результатов.

Я бы попробовал что-то вроде (не проверено):

var query = (from p in context.Products
             from m in p.Materials
             select new { p, m })
            .Union(
             from m in context.Materials
             from p in m.Products
             select new { p, m })
            ...

Возможно, вам придется использовать DefaultIfEmpty для принудительного выполнения внешних объединений.

...