2

从这样的传统 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) });

但我还需要访问IdOwner字段,而现在我只能访问CallTime.

4

3 回答 3

3

您无法在给定代码中访问 Id,因为您按所有者分组,并且组的密钥将是所有者而不是“流量”对象。

如果您按流量对象分组,您需要某种方式告诉 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)

作为结果。

于 2012-07-17T11:32:37.943 回答
2

您的 SQL 查询对我来说似乎无效:您正在使用Id但未按它分组。我假设您想按Idand分组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();
于 2012-07-17T10:58:17.887 回答
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;  

在该示例中,您选择组

于 2012-07-17T10:58:24.303 回答