0

我有一个Asset实体列表,每个实体Asset都有一个Field具有两个属性的实体列表,每个属性看起来像这样

| Index | Value |
| 0 | "hello" |
| 1 | "blah" |
| 2 | null |

在一个循环中我得到变量

i = 2i = 3

我有一个 linq 查询来尝试获取以下内容:Assets有一个对应的Field位置是,或者没有一个。ValueinullFieldIndex i

例如,如果i是 2,它将返回具有上表的资产,因为它有一个Fieldwhere 2 对应于null

而且,如果是 3,它也应该返回上面的,i因为没有3。FieldIndex

此代码有效:

var assets = (from a in assets where 
              a.Fields.Any(x => x.Index == i && x.Value == null) select a)
     .Union(from a in assets where 
              a.Fields.All(x => x.Index != i) select a)
     .ToList();

这不是很好,我想知道有没有办法在一个声明中做到这一点?

4

5 回答 5

7

其他答案有效,但如果您简化问题,它会变得更加简单:

assets.Where(a => !a.Fields().Any(f => f.Index == i &&
                                       f.Value != null))
      .ToList()

你想要所有Asset没有 aField和非 nullIndex的s 。你不需要把它分成两个条件。iValue

于 2013-05-31T15:24:01.647 回答
5

您不需要两个查询,只需使用一个和一个||

assets = assets
    .Where(a => a.Fields.Any(f => f.Index == i && f.Value == null)
            ||  a.Fields.All(f => f.Index != i))
    .ToList(); 
于 2013-05-31T15:20:00.780 回答
1

如我所见,您有几个选择:

  1. 仅在资产 ID 和索引上使用更传统的 LINQ 和 LEFT JOIN JOIN 语法。因此,如果 LEFT JOIN 返回 null(即DefaultIfEmpty()),则找不到该资产的索引。这就是案例#2。但是,如果它不为空,那么您可以where通过检查Valueis 来进一步过滤(即子句) null。这就是案例#1。
  2. 你可以结合where语句。 where a.Fields.Any(...) || a.Fields.All.

在我看来,你会想同时尝试它们,看看哪个更适合你的需求。我猜第一个选项会执行得更好,但是如果数据量很小,第二个选项肯定会容易得多。

于 2013-05-31T15:21:04.980 回答
0
var assets = assets.where(a => a.Fields.Any(x => x.Index == i && x.Value == null) || a.Fields.All(x => x.Index != i)).ToList();
于 2013-05-31T15:21:11.690 回答
0

在这种情况下,您实际上可以稍微缩短查询

 var assets = (
                from a in assets
                where a.Fields.All(x => x.Index != i || x.Value == null)
                select a
              ).ToList();
于 2013-05-31T15:23:36.253 回答