【问题标题】:Add missing dates to list将缺失的日期添加到列表中
【发布时间】:2017-12-02 18:26:42
【问题描述】:

我已经编写了一个解决方案,它基本上添加了缺失的日期,并将我的收藏中该日期的销售属性设置为 0,这样它就缺失了:

int range = Convert.ToInt32(drange);
var groupedByDate = tr.Union(Enumerable.Range(1, Convert.ToInt32(range))
                       .Select(offset => new MyClassObject
                       { 
                           Date = DateTime.Now.AddDays(-(range)).AddDays(offset), 
                           Sales = 0 
                       })).GroupBy(x => x.Date)
                          .Select(item => new MyClassObject
                          { 
                              Sales = item.Sum(x => x.Sales), 
                              Date = item.Key 
                          })
                           .OrderBy(x => x.Date)
                           .ToList();

第一个将 DB 中的日期分组且丢失的解决方案如下所示:

var groupedByDate = tr
                     .GroupBy(x => x.TransactionDate.Date)
                     .Select(item => new MyClassObject 
                     { 
                        Sales = item.Sum(x => x.QuantityPurchased), 
                        Date = item.Key.ToString("yyyy-MM-dd") 
                     })
                     .OrderBy(x => x.Date)
                     .ToList();

我不太喜欢我在第一个解决方案中的做法,代码看起来很乱,老实说我相信它可以用更好的方式编写..

有人可以帮我解决这个问题吗?

附:上面我展示的第一个解决方案效果很好,但是我想写一些更好的东西,看起来更漂亮,而且看起来很乱(我写的第一个解决方案)......

【问题讨论】:

  • 要获得完整的上下文,请解释 tr 和 drange 变量。
  • 你能不能选择日期范围,然后加入选择(日期,总销售额)?
  • @Emanuele tr 是我数据库中的交易... drange 是从视图传递的变量,它基本上代表了我将显示交易的一组日期。 Drange 可以是 = 30,21,14 或 7
  • 这属于 Code Review,而不是 SO。

标签: c# asp.net asp.net-mvc linq c#-4.0


【解决方案1】:

如何生成日期范围,然后将其与原始查询的结果连接起来。当没有匹配时,将Sales 设置为0

int range = 2;
var startDate = DateTime.Now;
var dates = Enumerable.Range(1, range)
            .Select(offset => startDate.AddDays(-offset).Date);

var groupedByDate = from date in dates
                    join tmp in groupedByDate on date equals tmp.Date into g
                    from gr in g.DefaultIfEmpty()
                    select new MyClassObject
                    {
                        Sales = gr == null ? 0 : gr.Sales,
                        Date = date
                    };

【讨论】:

  • @Magnus 嘿,它说如下:连接子句中的表达式之一的类型不正确。调用“GroupJoin”时类型推断失败?
  • 日期必须是 DateTime 而不是字符串。从原始查询中删除 .ToString("yyyy-MM-dd")
  • @Magnus 好的,现在开始测试 :)
  • 您还应该从原始查询中删除 OrderBy 和 ToList。
  • @Magnus 是的,谢谢。顺便提一句,。偏移量不应该添加 offset => startDate.AddDays(offset).Date 是负数吗?像这样: offset => startDate.AddDays(-offset).Date .... 因为如果负号不存在,则添加的偏移量将在未来(我只是在测试并注意到这一点)...跨度>
【解决方案2】:

这是执行此操作的简单方法:

var lookup = tr.ToLookup(x => x.TransactionDate.Date, x => x.QuantityPurchased);
var quantity = lookup[new DateTime(2017, 6, 29)].Sum();

如果你想要一个日期范围,那么就是这样:

var startDate = new DateTime(2017, 6, 1)
var query =
    from n in Enumerable.Range(0, 30)
    let TransactionDate = startDate.AddDays(n)
    select new
    {
        TransactionDate,
        QuantityPurchases = lookup[TransactionDate].Sum(),
    };

简单。

【讨论】:

    猜你喜欢
    • 2020-01-26
    • 1970-01-01
    • 2021-08-11
    • 1970-01-01
    • 2013-10-19
    • 1970-01-01
    • 1970-01-01
    • 2019-03-17
    • 2021-08-27
    相关资源
    最近更新 更多