c# - Linq 相当于分组选择

标签 c# mysql linq entity-framework

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

但我还需要访问 IdOwner 字段,而现在我只能访问 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/

相关文章:

c# - 使用未分配的变量(字符串)

php - 在一个查询中从两个不同的表中选择不同的行

php - 在 PHP 中有没有比 array_diff 更快的方法

c# - 参数 'd' 未绑定(bind)到指定的 LINQ to Entities 查询表达式中

c# - 如何在 .NET ASP C# 中正确使用 QueryString?

c# - 无法使用 autofac 解决通用存储库的依赖关系

C# 监视闭源类和原语的值更改

java - Java 中的任何 CSV Api,可以在大于 1 Gb 的 CSV 文件中来回遍历

c# - 否定表达式树中的方法调用

c# - 具有公差的 List<double> 的 GroupBy 不起作用