【问题标题】:LINQ to SQL: Select count rows for each date in a provided range?LINQ to SQL:为提供的范围内的每个日期选择计数行?
【发布时间】:2011-10-24 14:25:11
【问题描述】:

我有一个表 Account,其中有一列名为 CreatedOn(可为空的日期时间)。

我正在编写一个方法,它接受两个参数 from 和 to(DateTime 对象),我想选择 from 和 to 之间的所有日期以及在每个日期创建的 T 中的行数。

如何在 LINQ 中以优雅而有效的方式做到这一点?

我尝试这样做,但它似乎为列表日期中的每个日期查询数据库一次:

static void Test(DataClasses1DataContext context, DateTime from, DateTime to)
{
    List<DateTime> dates = new List<DateTime>();
    while (from <= to)
    {
        dates.Add(from.Date);
        from = from.AddDays(1);
    }

    var result = dates.Select(d => new { Date = d, Count = context.Accounts.Count(a => a.CreatedOn.HasValue && a.CreatedOn.Value.Date == d) });
    foreach (var row in result)
            Console.WriteLine(row.Date + "   " + row.Count);
}

【问题讨论】:

  • 不清楚最后一部分是什么意思 - 如果您想按其他方面进行分组,当您只获取“每日匹配项”时,您希望它如何工作?
  • 假设 T 还有另一个名为 CreatedByAdmin 的列。我希望查询易于扩展,以便我可以按 Date 和 CreatedByAdmin 分组,并为每个此类组合选择行数。
  • 说实话,您并不清楚您希望该查询结果的形状是什么 - 尤其不是 开始 已经按日期分组的内容。
  • 好的,我已经稍微改述了这个问题,所以不要太在意可扩展性。

标签: c# linq linq-to-sql


【解决方案1】:

已更新以回应评论

我不会说它很优雅,但它只查询数据库一次。

static void Test(DataClasses1DataContext context, DateTime fromDate, DateTime toDate)
{
    var result = context.Accounts
                .Where(p => p.CreatedOn >= fromDate && p.CreatedOn <= toDate)
                .GroupBy(x => x.CreatedOn.Date)
                .Select(x => new {
                   dt = x.Key,
                   count = x.Count()});
}

List<DateTime> dates = new List<DateTime>();
while (fromDate <= toDate)
{
    dates.Add(fromDate.Date);
    fromDate = fromDate.AddDays(1);
}    

var allDates = dates.Select(x => new {
                    dt = x,
                    count = 0});

// Merge both lists and then filter to include highest count
var result = rows.Concat(allDates)
                 .GroupBy(x => x.dt)
                 .Select(x => new {
                    dt = x.Key,
                    count = x.OrderByDescending(c => c.count)
                             .FirstOrDefault().count});

【讨论】:

  • 如果您只想要有行的日期,但我也想要那些有零行的日期,那么您的方法有效。我当然可以创建一个包含所有日期的新列表,如果有 1,则使用结果中的值,否则使用 0。有没有更优雅的方式来做到这一点?
猜你喜欢
  • 2019-09-05
  • 1970-01-01
  • 1970-01-01
  • 2016-04-07
  • 1970-01-01
  • 2023-03-07
  • 2016-02-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多