来自这样的传统 SQL 语句:
SELECT Id, Owner, MIN(CallTime)
FROM traffic
WHERE CallType = "IN"
GROUP BY Owner;
其中CallTime
是一个日期时间字段,我想要的是属于每个Owner
的最旧记录。
如何使用 Linq 实现此目的?
这是我的尝试(我正在使用 Entity Framework ,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
。
最佳答案
您无法在给定代码中访问 Id,因为您是按所有者分组,并且该组的 key 将是所有者而不是“流量”对象。
如果您按流量对象进行分组,则需要某种方式来告诉 groupBy 如何正确比较它们(即按所有者分组),这可以使用 IEqualityComparer 来完成
例如
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)
作为结果。
关于c# - Linq 相当于分组选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11520991/