Linq命令按日期分组 - 如何分组

时间:2017-01-18 19:03:52

标签: c# linq

我正在尝试创建一个Iqueryable方法,该方法返回每天服务的连接数。此数据从SQL Server数据库中读取。

这是ConnectionItem类

public class ConnectionItem
{
    public DateTime CreatedDate { get; set; }
    public int NumberOfConnections { get; set; }
}

这是我的iqueryable

private IQueryable<ConnectionItem> ListItems(DataContext dataContext)
{
    return dataContext.Connections
        .Join(dataContext.Configurations,
            connections => connections.ConfigID,
            config => config.ConfigID,
            (connections, config) => new { cx = connections, cf = config })
        .Join(dataContext.Users,
            config => config.cf.UserID,
            users => users.UserID,
            (config, users) => new { cf = config, su = users})
            .Where(q => q.su.AccountEventID == 123 && q.cf.cx.Successful == true)
            .GroupBy(g => g.cf.cx.CreatedDate.ToShortDateString())
            .Select(s => new ConnectionItem
            {
                CreatedDate = ????,
                NumberOfConnections = ????
            });
}

如何访问分组的日期值和每组的项目数?

另外,有没有更简单的方法来编写这种语句?我不是100%确定别名cx,cf等是如何工作的。

赞赏任何意见。

3 个答案:

答案 0 :(得分:2)

Date个对象的DateTime部分分组。 Date属性只会删除时间部分。您将日期转换为字符串,以免失去DateTime对象的保真度。

var eventId = 123;
return dataContext.Connections.Join(dataContext.Configurations,
        conn => conn.ConfigID,
        cfg => cfg.ConfigID,
        (conn, cfg) => new { conn, cfg })
    .Join(dataContext.Users,
        x => x.cfg.UserID,
        u => u.UserID,
        (x, u) => new { x.conn, u })
    .Where(x => x.conn.Successful && x.u.AccountEventID == eventId)
    .GroupBy(x => x.conn.CreatedDate.Date)
    .Select(g => new ConnectionItem
    {
        CreatedDate = g.Key,
        NumberOfConnections = g.Count(),
    });

使用查询语法可以更好地表达上述内容。

var eventId = 123;
return
    from conn in dataContext.Connections
    join cfg in dataContext.Configurations on conn.ConfigID equals cfg.ConfigID
    join u in dataContext.Users on cfg.UserID equals u.UserID
    where conn.Successful && u.AccountEventID == eventId
    group 1 by conn.CreatedDate.Date into g
    select new ConnectionItem
    {
        CreatedDate = g.Key,
        NumberOfConnections = g.Count(),
    };

答案 1 :(得分:0)

.GroupBy linq方法返回IGrouping<TKey, TValue>,它基本上是一个具有Key属性的List,您刚刚将其分组。

所以这里

Select(s => new ConnectionItem
        {
            CreatedDate = ????,
            NumberOfConnections = ????
        });

您通过IEnumerable<IGrouping<TKey,TValue>>进行迭代,以便您可以执行此操作

Select(s => new ConnectionItem
        {
            CreatedDate = s.Key
            NumberOfConnections = s.Count()
        });

已修改根据评论,我意识到您要查找的数字不是实际列表

答案 2 :(得分:0)

只需致电s.Keys.Count(),即可获得:

private IQueryable<ConnectionItem> ListItems(DataContext dataContext)
    {
        return dataContext.Connections
            .Join(dataContext.Configurations,
                connections => connections.ConfigID,
                config => config.ConfigID,
                (connections, config) => new {cx = connections, cf = config})
            .Join(dataContext.Users,
                config => config.cf.UserID,
                users => users.UserID,
                (config, users) => new {cf = config, su = users})
            .Where(q => q.su.AccountEventID == 123 && q.cf.cx.Successful == true)
            .GroupBy(g => g.cf.cx.CreatedDate.ToShortDateString())
            .Select(s => new ConnectionItem
            {
                CreatedDate = s.Key,
                NumberOfConnections = s.Count()
            });
    }
  

group子句返回一个IGrouping序列   包含零个或多个与键值匹配的项的对象   群组。例如,您可以根据字符串序列进行分组   到每个字符串中的第一个字母。在这种情况下,第一个字母是   键和char类型,并存储在每个键的Key属性中   IGrouping对象。编译器推断出的类型   键。

Group clause docs