有没有更好的方法来编写这个linq查询
本文关键字:linq 查询 更好 方法 有没有 | 更新日期: 2023-09-27 18:16:21
我有一个Asset
实体列表,每个Asset
有一个具有两个属性的Field
实体列表,每一个属性看起来都像这个
| Index | Value |
| 0 | "hello" |
| 1 | "blah" |
| 2 | null |
在一个循环中,我得到变量
CCD_ 8和CCD_ 9
我有一个linq查询,试图得到以下内容:具有Field
的Assets
,其中对应于i
的Value
是null
,或者不存在具有Index
i
的Field
。
例如,如果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();
这不是很好,我想知道有没有办法在一个声明中做到这一点?
其他答案都有效,但如果你简化问题,它会变得更加简单:
assets.Where(a => !a.Fields().Any(f => f.Index == i &&
f.Value != null))
.ToList()
您需要所有没有Field
、Index
为i
和非空Value
的Asset
。你不需要把它分成两个条件。
您不需要两个查询,只需使用一个带有||
:的查询即可
assets = assets
.Where(a => a.Fields.Any(f => f.Index == i && f.Value == null)
|| a.Fields.All(f => f.Index != i))
.ToList();
在我看来,您有几个选项:
- 只对AssetID和Index使用LINQ和LEFTJOIN的更传统的JOIN语法。因此,如果LEFT JOIN返回null(即
DefaultIfEmpty()
(,则没有找到该资产的索引。这是第二种情况。但是,如果它不是null,那么您可以通过检查Value
是null
来进一步筛选(即where
子句(。这是第一种情况 - 您可以组合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();