有没有更好的方法来编写这个linq查询

本文关键字:linq 查询 更好 方法 有没有 | 更新日期: 2023-09-27 18:16:21

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

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

在一个循环中,我得到变量

CCD_ 8和CCD_ 9

我有一个linq查询,试图得到以下内容:具有FieldAssets,其中对应于iValuenull,或者不存在具有Index iField

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

并且,如果i是3,它也应该返回上面的内容,因为不存在Index为3的Field

此代码有效:

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();

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

有没有更好的方法来编写这个linq查询

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

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

您需要所有没有FieldIndexi和非空ValueAsset。你不需要把它分成两个条件。

您不需要两个查询,只需使用一个带有||:的查询即可

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

在我看来,您有几个选项:

  1. 只对AssetID和Index使用LINQ和LEFTJOIN的更传统的JOIN语法。因此,如果LEFT JOIN返回null(即DefaultIfEmpty()(,则没有找到该资产的索引。这是第二种情况。但是,如果它不是null,那么您可以通过检查Valuenull来进一步筛选(即where子句(。这是第一种情况
  2. 您可以组合where语句。CCD_ 34

在我看来,你应该同时尝试一下,看看哪一种更适合你的需求。我想第一个选项会表现得更好,但如果数据大小较小,第二个选项肯定会容易得多。

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

在这种情况下,您实际上可以将查询缩短一点

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