【问题标题】:Linq outer join with conditions带条件的 Linq 外连接
【发布时间】:2013-09-13 12:05:24
【问题描述】:

我需要一个高效的 LINQ 查询(如果可能,在方法语法中)从集合 A 中获取所有没有对应键的项目 在第二个集合 B(1 到 n)中,或者如果 B 中存在元素,则只取那些 MyValue 为空的元素。简而言之:返回 A 中不存在于 B 中的所有元素,或者如果它们存在于 B 中且至少有一行具有 MyValue = null。

table A
{
  int MyKey (primary_key);
}

table B
{ 
  int MyKey (foreign_key to A.MyKey);
  string MyValue;
}

我正在尝试 except(),但这仅在两个集合属于同一类型时才有效。 我正在尝试 GroupJoin(),但我没有找到加入后如何删除重复项的方法。

a.GroupJoin(
 b.Where(item => item.Value = null), 
 el => el.MyKey, 
 el2 => el2.MyKey,
 (el3, el4) => el3); 

这样,我过滤掉 B 中的项目,因为它们不再存在而再次加入。

在纯sql中很容易实现:

select * from A a left join B b on a.MyKey = b.MyKey where MyValue is null;

【问题讨论】:

    标签: c# sql database linq


    【解决方案1】:

    嗯,它在 LINQ 语法中更漂亮:

    var result = (
        from a in aCollection
        join b in bCollection on a.Key equals b.AKey into bSubCollection
        where !bSubCollection.Any(x => x.Value != null)
        select a
    );
    

    但这里也是方法语法:

    var result = aCollection
        .GroupJoin(bCollection, a => a.Key, b => b.AKey, (a, bSub) => new { a, bSub })
        .Where(c => !c.bSub.Any(x => x.Value != null))
        .Select(c => c.a);
    

    本质上,您是通过ab 的集合加入匿名类型,然后通过是否有任何bs 过滤c 的集合(a 已经不同)带有非空 Value

    【讨论】:

    • 就是这样!我只使用了“c.bSub.All(x => x.Value == null)”而不是“!c.bSub.Any(x => x.Value != null))”
    【解决方案2】:

    您需要翻译方法语法,但您编写的左外连接的查询语法应该如下:

     var query = from itemA in a
            join itemB in b on
                itemA.MyKey equals itemB.MyKey into joinTable
            from itemB in joinTable.DefaultIfEmpty()
            where (itemB == null) || (itemB.MyValue == null)
            select itemA;
    

    您需要对结果应用 distinct。 你可以看到以下帖子: Distinct by property of class by linq

    或者在MoreLinq中使用DistinctBy

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-12
      • 1970-01-01
      • 1970-01-01
      • 2012-12-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多