来自这样的传统SQL语句:
SELECT Id, Owner, MIN(CallTime)
FROM traffic
WHERE CallType = "IN"
GROUP BY Owner;
其中CallTime
是日期时间字段,我想要的是属于每个Owner
的最旧记录。
如何使用Linq实现这一目标?
这是我的尝试(我正在使用实体框架,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) });
但我还需要访问Id
和Owner
字段,而现在我只能访问CallTime
。
答案 0 :(得分:3)
您无法在给定代码中访问ID,因为您按所有者进行分组,而该组的密钥将是所有者而非“流量”对象。
如果按流量对象分组,则需要某种方式告诉groupBy如何正确比较它们(即按所有者分组)这可以通过IEqualityComparer来完成
e.g。
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 };
}); }
这给出了
ID : Owner : MinCallTime
1 : A : (01/01/2012 00:00:00)
5 : B : (01/01/2011 00:00:00)
作为结果。
答案 1 :(得分:2)
您的SQL查询对我来说看起来不合适:您使用的是Id
,但没有使用它进行分组。我假设您想按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();
如果您想获得最早的(最小的)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();
答案 2 :(得分:0)
// 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;
在该示例中,您选择了组