考虑以下对象:
public class Address { public string city; public string state; public string country; }
如果我有一个地址列表,我该如何使用LINQ来获取城市、州和国家相匹配的计数列表。
所以我的结果可能是这样的:
- "普林斯顿" "新泽西州" "美国" 122
- "奥斯汀" "德克萨斯州" "美国" 44
- "洛杉矶" "加利福尼亚州" "美国" 1
- "普林斯顿" "na" "英国" 3
- ....
var qry = from addr in addresses
group addr by new { addr.city, addr.state, addr.country } into grp
select new
{
city = grp.Key.city,
state = grp.Key.state,
country = grp.Key.country,
count = grp.Count(),
};
var qry = addresses.GroupBy(addr => new { addr.city, addr.state, addr.country});
foreach(var row in qry) {
Console.WriteLine("{0} {1} {2} \t {3}",
row.Key.city, row.Key.state, row.Key.country, row.Count());
}
.Key
是复合键 new { addr.city, addr.state, addr.country}
,每个组还是IEnumerable<Address>
。请注意,对于数据库查询,您应该提前告诉它您的全部意图,例如:var qry = from addr in db.Addresses
group addr by new { addr.city, addr.state, addr.country} into grp
select new {
grp.Key.city, grp.Key.state,
grp.Key.country, Count = grp.Count()
};
这样它就有最好的机会进行合理的查询(而不是n+1)。
这是我在LINQPAD中尝试过的,并且它运行良好(类似于Enigmativity的答案):
void Main()
{
List<Address> lst = new List<Address>();
lst.Add(new Address{ city = "ny", state = "cy", country = "india"});
lst.Add(new Address{ city = "ny", state = "cy", country = "india"});
lst.Add(new Address{ city = "by", state = "cy", country = "india"});
lst.Add(new Address{ city = "ny", state = "fr", country = "india"});
var qry = from addr in lst
group addr by new { addr.city, addr.state, addr.country } into grp
select new
{
city = grp.Key.city,
state = grp.Key.state,
country = grp.Key.country,
count = grp.Count(),
};
qry.Dump();
}
public class Address { public string city; public string state; public string country; }
纽约,Cy,印度 2
柏林,Cy,印度 1
纽约,法兰克福,印度 1