3

我需要一个有效的 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;
}

我正在尝试例外(),但这仅在两个集合属于同一类型时才有效。我正在尝试 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;
4

2 回答 2

2

嗯,它在 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);

a本质上,您是使用和 的集合加入匿名类型,然后仅通过是否有任何具有非 null 的 s 来b过滤c(已经不同) 的集合。abValue

于 2013-09-13T13:04:25.280 回答
0

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

 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

于 2013-09-13T13:03:44.230 回答