【问题标题】:FULL OUTER JOIN on a Many-to-Many with LINQ Entity Framework使用 LINQ 实体框架在多对多上进行 FULL OUTER JOIN
【发布时间】:2012-01-24 13:35:48
【问题描述】:

我有产品 (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 中执行此操作?

非常感谢!

【问题讨论】:

  • 此时,由于 LINQ 中的完全外连接似乎令人头疼,我正在考虑一个视图,我将在其上运行 LINQ 查询。该视图将具有必要的 JOINS,并且 LINQ 查询变得更加容易。

标签: sql entity-framework many-to-many outer-join full-outer-join


【解决方案1】:

以下应该可以完成工作:

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 

【讨论】:

    【解决方案2】:

    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 来强制执行外连接。

    【讨论】:

      【解决方案3】:

      从你的描述看来你确实需要:

      1. 所有产品
      2. 所有未使用的材料

      您需要将它作为单个 IQueryable(如果需要,您需要哪些字段)还是作为 2 个 IQueryable?

      【讨论】:

      • 嗯,我真的需要所有产品,是的,但也需要所有材料,这取决于用户想要什么。用户可以选择他是否特别想要与产品关联的材料,或尚未关联的材料。
      猜你喜欢
      • 2013-04-16
      • 1970-01-01
      • 1970-01-01
      • 2021-09-06
      • 1970-01-01
      相关资源
      最近更新 更多