LINQ to Object - 如何为子组实现 WHERE 子句“如果至少有一个元素是”
Posted
技术标签:
【中文标题】LINQ to Object - 如何为子组实现 WHERE 子句“如果至少有一个元素是”【英文标题】:LINQ to Object - How to implement WHERE clause `If at least one of the elements is` for sub-group 【发布时间】:2021-12-16 04:57:13 【问题描述】:我有一种无序记录:
public class Row
public string Client get; set;
public string Account get; set;
public string Status get; set;
它的实例化是:
List<Row> accounts = new List<Row>()
new Row() Client = "123", Account = "123.def", Status = "Open" ,
new Row() Client = "456", Account = "456.def", Status = "Closed" ,
new Row() Client = "123", Account = "123.abc", Status = "Open" ,
new Row() Client = "789", Account = "789.abc", Status = "Open" ,
new Row() Client = "456", Account = "456.abc", Status = "Closed" ,
new Row() Client = "789", Account = "789.ghi", Status = "Open" ,
new Row() Client = "789", Account = "789.def", Status = "Closed" ,
new Row() Client = "789", Account = "789.jkl", Status = "Open" ,
;
输出是:
+--------+---------+--------+
| Client | Account | Status |
+--------+---------+--------+
| 123 | 123.def | Open |
+--------+---------+--------+
| 456 | 456.def | Closed |
+--------+---------+--------+
| 123 | 123.abc | Open |
+--------+---------+--------+
| 789 | 789.abc | Open |
+--------+---------+--------+
| 456 | 456.abc | Closed |
+--------+---------+--------+
| 789 | 789.ghi | Open |
+--------+---------+--------+
| 789 | 789.def | Closed |
+--------+---------+--------+
| 789 | 789.jkl | Open |
+--------+---------+--------+
之后,为了进一步操作对象,我输入了以下附加类型:
public class Client
public string Code get; set;
public List<Account> Accounts get; set;
public class Account
public string Number get; set;
public string Status get; set;
并对按客户字段分组的行进行选择投影:
List<Client> clients = accounts
.GroupBy(x => x.Client)
.Select(y => new Client()
Code = y.Key,
Accounts = y.GroupBy(z => z.Account)
.Select(z => new Account()
Number = z.First().Account,
Status = z.First().Status
).ToList()
).ToList();
我得到了输出:
+------+------------------+
| Code | Accounts |
| +---------+--------+
| | Number | Status |
+------+---------+--------+
| 123 | 123.def | Open |
| +---------+--------+
| | 123.abc | Open |
+------+---------+--------+
| 456 | 456.def | Closed |
| +---------+--------+
| | 456.abc | Closed |
+------+---------+--------+
| 789 | 789.abc | Open |
| +---------+--------+
| | 789.ghi | Open |
| +---------+--------+
| | 789.def | Closed |
| +---------+--------+
| | 789.jkl | Open |
+------+---------+--------+
但是,我的问题是:
如何为过滤的Accounts
子组实现 WHERE 子句?
例如:
• How where-clause for logic: get clients, all of whose accounts is open
for getting this?:
+------+------------------+
| Code | Accounts |
| +---------+--------+
| | Number | Status |
+------+---------+--------+
| 123 | 123.def | Open |
| +---------+--------+
| | 123.abc | Open |
+------+---------+--------+
• How where-clause for logic: get clients, who have at least one account is open?
for getting this?:
+------+------------------+
| Code | Accounts |
| +---------+--------+
| | Number | Status |
+------+---------+--------+
| 123 | 123.def | Open |
| +---------+--------+
| | 123.abc | Open |
+------+---------+--------+
| 789 | 789.abc | Open |
| +---------+--------+
| | 789.ghi | Open |
| +---------+--------+
| | 789.def | Closed |
| +---------+--------+
| | 789.jkl | Open |
+------+---------+--------+
dotnetfiddle 上的完整互动 code listing
【问题讨论】:
【参考方案1】:查询:获取客户,其所有账户均已开通
var ClientsWithAllAccountsAsOpen = clients
.Where(c => c.Accounts
.All(a => a.Status == "Open"));
// Add ToList() or equivalent if you need to materialise.
查询:获取至少有一个账户已开通的客户
var ClientsWithAtLeastOneOpenAccounts = clients
.Where(c => c.Accounts
.Any(a => a.Status == "Open"));
// Add ToList() or equivalent if you need to materialise.
【讨论】:
【参考方案2】:get clients, all of whose accounts is open
:
var openAccountsByClient = accounts
.Where(e => e.Status == "Open")
.GroupBy(x => x.Client)
.Select(y => new Client()
...
).ToList();
get clients, who have at least one account is open?
:
var accountsByClientsWithOneAccount = accounts
.GroupBy(x => x.Client)
.Where(x => x.Any(e => e.Status == "Open"))
.Select(y => new Client()
...
).ToList();
【讨论】:
以上是关于LINQ to Object - 如何为子组实现 WHERE 子句“如果至少有一个元素是”的主要内容,如果未能解决你的问题,请参考以下文章
LINQ to Object——延时执行的Enumerable类方法
C# Object to Json to Xml,如何为数组项生成xml元素