[英]Linq equivalent for grouping select
From a traditional SQL sentence like this: 从像这样的传统SQL语句中:
SELECT Id, Owner, MIN(CallTime)
FROM traffic
WHERE CallType = "IN"
GROUP BY Owner;
where CallTime
is a datetime field, what I want is the oldest record belonging to each Owner
. 其中
CallTime
是日期时间字段,我想要的是属于每个Owner
的最旧记录。
How can I achieve this with Linq? 如何使用Linq做到这一点?
This was my attempt (I'm using Entity Framework and context
is the entity instance): 这是我的尝试(我使用的是实体框架,
context
是实体实例):
var query = context.traffic.Where(t => t.CallType == "IN");
var results = query
.GroupBy(t => t.Owner)
.Select(g => new { CallTime = g.Min(h => h.CallTime) });
But I need also access to Id
and Owner
fields whereas now I have only access to CallTime
. 但是我还需要访问
Id
和Owner
字段,而现在我只能访问CallTime
。
You cannot access Id in the given code because you are grouping by Owner and the Key to the group will be the Owner not the 'traffic' object. 您无法访问给定代码中的ID,因为您正在按所有者分组,并且该组的密钥将是所有者而不是“流量”对象。
If you group by traffic objects you need some way to tell the groupBy how to compare them properly (ie group by owner) This can be done with an IEqualityComparer 如果按流量对象分组,则需要某种方式来告诉groupBy如何正确比较它们(即按所有者分组)这可以通过IEqualityComparer来完成
eg 例如
private class Traffic {
public int Id { get; set; }
public string Owner { get; set; }
public DateTime CallTime { get; set; }
}
private class TrafficEquaityComparer : IEqualityComparer<Traffic> {
public bool Equals(Traffic x, Traffic y) {
return x.Owner == y.Owner;
}
public int GetHashCode(Traffic obj) {
return obj.Owner.GetHashCode();
}
}
private static TrafficEquaityComparer TrafficEqCmp = new TrafficEquaityComparer();
private Traffic[] src = new Traffic[]{
new Traffic{Id = 1, Owner = "A", CallTime = new DateTime(2012,1,1)}, // oldest
new Traffic{Id = 2, Owner = "A", CallTime = new DateTime(2012,2,1)},
new Traffic{Id = 3, Owner = "A", CallTime = new DateTime(2012,3,1)},
new Traffic{Id = 4, Owner = "B", CallTime = new DateTime(2011,3,1)},
new Traffic{Id = 5, Owner = "B", CallTime = new DateTime(2011,1,1)}, //oldest
new Traffic{Id = 6, Owner = "B", CallTime = new DateTime(2011,2,1)},
};
[TestMethod]
public void GetMinCalls() {
var results = src.GroupBy(ts => ts, TrafficEqCmp)
.Select(grp => {
var oldest = grp.OrderBy(g => g.CallTime).First();
return new { Id = oldest.Id,
Owner = grp.Key.Owner,
CallTime = oldest.CallTime };
}); }
this gives 这给
ID : Owner : MinCallTime
1 : A : (01/01/2012 00:00:00)
5 : B : (01/01/2011 00:00:00)
as the results. 作为结果。
Your SQL query doesn't look valid to me: you're using Id
but not grouping by it. 您的SQL查询对我而言无效:您使用的是
Id
,但未按其分组。 I assume that you wanted to group by Id
and Owner
? 我假设您想按
Id
和Owner
分组?
var results = query
.GroupBy(t => new {Id = t.Id, Owner = t.Owner})
.Select(g => new { Id = g.Key.Id, Owner = g.Key.Owner, CallTime = g.Min(h => h.CallTime) })
.ToList();
If you want to get the oldest (smallest) ID
instead of grouping by it: 如果要获取最旧的(最小的)
ID
而不是按其分组:
var results = query
.GroupBy(t => t.Owner)
.Select(g => new { Id = g.Min(x => x.Id), Owner = g.Key, CallTime = g.Min(h => h.CallTime) })
.ToList();
// custQuery
is an IEnumerable<IGrouping<string, Customer>>
//
custQuery
是IEnumerable<IGrouping<string, Customer>>
var custQuery =
from cust in customers
group cust by cust.City into custGroup
where custGroup.Count() > 2
orderby custGroup.Key
select custGroup;
In that example you select the group 在该示例中,选择组
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.