具有条件的 Linq 外部联接

本文关键字:外部 Linq 有条件 | 更新日期: 2023-09-27 18:31:22

>我需要一个高效的 LINQ 查询(如果可能,使用方法语法)来获取集合 A 中没有相应键的所有项目在第二个集合 B(1 到 n)中,或者如果 B 中存在元素,则仅采用具有 MyValue null 的元素。简而言之:返回 B 中不存在的所有 A 元素,或者如果它们存在于 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;

具有条件的 Linq 外部联接

嗯,它在 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集合的匿名类型的组,然后只需通过是否有任何具有非空Valueb来过滤c集合(a已经是不同的)。

您需要

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

 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;

您需要对结果应用不同的。您可以看到以下帖子:按 linq 的类属性区分

或在 MoreLinq 中使用 DistinctBy