Reputation: 3677
I have a many-to-many relationship of products (p) and materials (m) and the products2materials table (p2m) as the many-to-many link.
I need to get
- all products that have materials assigned,
- all products with no materials assigned,
- and all materials with no products assigned.
Basically a union of what is there. However, since this will be a data filter, I need to filter out products and/or materials that do not match the search criteria (e.g. all products that start with "A", etc.).
How do I do this in LINQ-to-EF 4.1?
Many thanks!
Upvotes: 0
Views: 2792
Reputation: 12711
The following should do the job:
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
For performance it would probably be better the following:
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
Upvotes: 1
Reputation: 364279
Linq doesn't offer full outer join operation directly so your best choice is to try separate left and right join L2E queries and union them to single result set.
I would try something like (not tested):
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 })
...
Perhaps you will have to use DefaultIfEmpty
to enforce outer joins.
Upvotes: 0