c# - LINQ Fluent 语法 - 取消选择数组中的项目
问题描述
我正在为 Fluent LINQ 查询而苦苦挣扎。我有一个Contributor
带有Product
数组的对象:
public class Product
{
public int Id {get;set;}
public string Role {get;set;}
public string Publisher {get;set;}
}
public class Contributor
{
public string Id {get;set;}
public string Name {get;set;}
public Product[] ProductsContributedTo {get;set;}
}
我有一个集合,Contributor
我想过滤这些集合,以便:
我只选择数组
Contributor
中存在作者角色记录的记录。Contributor.ProductsContributedTo
每个贡献者
Contributor.ProductsContributedTo
数组应该只包含作者角色。
到目前为止,这是我的尝试:
var authors = contributors.SelectMany(people => people.ProductsContributedTo
.Where(product => product.Role == "Author")
.Select(c => people))
.ToList();
因此,这是可行的,我正在选择正确的贡献者记录,但是如何过滤Contributor.ProductsContributedTo
以仅包含作者角色?
这是一个小提琴,证明我有 3 条贡献者记录Barry Collins、Maggie Fenwick和Sedgewick Foley。上面的 LINQ 查询只正确选择了 Maggie Fenwick 和 Barry Collins,但是如何过滤Contributor.ProductsContributedTo
数组以便我只有他们各自的 Author Product 记录?
https://dotnetfiddle.net/hScdi4
编辑:
我对 Fiddle 做了一点改动,因为每个都Contributor
可以 Author multipleProduct
所以我想澄清一下。
解决方案
它比你想象的要复杂得多:
List<Contributor> authors = contributors
.Where(x => x.ProductsContributedTo.Any(y => y.Role == "Author"))
.Select(x => new Contributor { Id = x.Id, Name = x.Name, ProductsContributedTo = x.ProductsContributedTo.Where(y => y.Role == "Author").ToArray() })
.ToList();
您必须将其“克隆”Contributor
到Contributor
具有过滤ProductsContributedTo
列表的新对象。
请注意,我过滤了两次Role == "Author"
,一次用于过滤Contributor
s,一次用于过滤ProductsContributedTo
所选Contributor
s` 的。
其他方式,不重复检查Role
是这样的:
List<Contributor> authors = contributors
.Select(x => new { Contributor = x, FilteredProducts = x.ProductsContributedTo.Where(y => y.Role == "Author").ToArray() })
.Where(x => x.FilteredProducts.Length != 0)
.Select(x => new Contributor { Id = x.Contributor.Id, Name = x.Contributor.Name, ProductsContributedTo = x.FilteredProducts })
.ToList();
我们将过滤后的“保存”在匿名对象中ProductsContributedTo
,然后使用它FilteredProducts
来过滤Contributor
s。这或多或少等同于将let
关键字与基于关键字的 linq 一起使用:
List<Contributor> authors = (from x in contributors
let filteredProducts = x.ProductsContributedTo.Where(y => y.Role == "Author").ToArray()
where filteredProducts.Length != 0
select new Contributor { Id = x.Id, Name = x.Name, ProductsContributedTo = filteredProducts }
).ToList();
Contributor
请注意,通常您可以使用分别包含 the及其过滤的 s的匿名对象生活得很好Product
,同时保持在sContributor
的完整列表中Product
:
List<Contributor> authors = contributors
.Select(x => new
{
Contributor = x,
FilteredProducts = x.ProductsContributedTo.Where(y => y.Role == "Author").ToArray()
})
.Where(x => x.FilteredProducts.Length != 0)
.ToList();
推荐阅读
- powershell - 如何在 EWS 的最后一天收到消息?
- react-native - react-native with redux deleteTodo 动作错误
- sql - Oracle Apex - 更改图表标签
- java - 是否可以仅使用循环将二进制转换为十进制
- routing - Hystrix 即服务
- android - 根据特定参数获取 Firebase 数据库参考 - Android Studio
- android - 反应本机获取请求失败
- python - 熊猫数据框循环
- c# - AppWidget 夜间网络超时
- javascript - 如何在jShowoff中检测更改幻灯片事件之前和之后?