【问题标题】:Linq expression to select rows when no other row in the table matches a condition当表中没有其他行与条件匹配时,Linq 表达式选择行
【发布时间】:2013-01-04 17:13:45
【问题描述】:

我有一个包含 3 列的表格:


名称 varchar

Test1

Test2

varchar


目标:

我想选择每个组的每个名称中只有 test1 为真的所有行。


为了澄清,以这些示例记录为例:

Name | Test1 | Test2 | Group
Foo    True    False   Group 1
Bar    True    False   Group 1
Bar    False   True    Group 2
Foo    False   True    Group 1
123    True    False   Group 1

将选择第 2 行,因为它从未为具有相同“名称”值的同一组的 Test2 测试为真。

第一行将不会被选中,因为它在表中的某个位置对具有相同组名的 Test2 进行了测试。

最后一行将被选中,因为它从未对 Test2 进行过测试。

注意:我有明确搜索的组名。

我的尝试

我尝试过(并且有效)是选择测试 1 为真的所有行。然后,我对每个 id 进行了另一次搜索(遍历第一个查询的结果)并测试它是否再次出现。我在这里所做的是一种解决方法,我知道 Linq 有很多“不存在的地方”功能,我想利用它们来改善我到目前为止所写内容的状态,所以希望我能把它全部推出一个语句。

代码示例

var items = itemsTable.Where(o => o.Group.Equals(GroupName) && o.Test1);

【问题讨论】:

  • 结果的目标和预测有矛盾
  • 只是为了理解这个例子,你说“第二行将被选中,因为它从来没有为同一组的 Test2 测试过。”我看到同一组的第 4 行 test2 = true,也许我误解了?
  • 是的,但“名称”不同。谢谢。

标签: c# sql linq where


【解决方案1】:
var items = itemsTable.Where(o => !o.Test2 && 
    !itemsTable.Any(x => x.Name == o.Name && x.Group == o.Group && x.Test2));

【讨论】:

  • 很好的编辑和很好的整体解决方案。非常感谢这位朋友。通过阅读和使用它,我已经学到了很多东西。
  • 我认为您查询 itemsTable 两次,不是吗?就像一个嵌套的 sql 选择
  • 几乎是的,我现在不知道有什么更优雅的方法。这样就行了。
  • 是的,它就像嵌套的 SQL 选择(但这与查询表两次不同)。您还需要对数据进行两次检查——首先是分组,然后是过滤(Any 调用)——这是不可避免的
【解决方案2】:

您可以使用以下内容:

var items = itemsTable.GroupBy(e => new { e.Name, e.Group }, e => e)
     .Where(g => !g.Any(e => e.Test2) &&  g.Key.Group.Equals(groupName))
     .SelectMany(e => e).ToList();

【讨论】:

    猜你喜欢
    • 2012-06-13
    • 2011-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-29
    • 2011-05-19
    • 1970-01-01
    • 2018-07-29
    相关资源
    最近更新 更多