Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用LINQ按n天对数据分组_C#_Linq - Fatal编程技术网

C# 使用LINQ按n天对数据分组

C# 使用LINQ按n天对数据分组,c#,linq,C#,Linq,我有以下课程: public class TotalPaymentStatistics { public DateTime RegisteredAt { get; set; } public double TotalAmount { get; set; } } <pre> void Main() { var items = new List<TotalPaymentStatistics>() { new Tot

我有以下课程:

public class TotalPaymentStatistics 
{ 
     public DateTime RegisteredAt { get; set; }
     public double TotalAmount { get; set; }  
}
<pre>
void Main()
{
    var items = new List<TotalPaymentStatistics>()
    {
        new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,1),TotalAmount = 120},
        new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,2),TotalAmount = 120},
        new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,3),TotalAmount = 120},
        new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,4),TotalAmount = 120},
        new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,5),TotalAmount = 120},
        new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,6),TotalAmount = 120},
        new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,7),TotalAmount = 120},
        new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,8),TotalAmount = 120},
        new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,9),TotalAmount = 120},
        new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,10),TotalAmount = 120},
    };
    DateTime day0 = items[0].RegisteredAt.AddDays(-1);
    var q = items
        .GroupBy(x => ((int)((x.RegisteredAt.Subtract(day0).TotalDays-1) / 5)))
        .Select(x => new {
            x.Key,
            Date = day0.AddDays(x.Key*5+1),
            Amount = x.Sum(y => y.TotalAmount)
        });
    foreach(var item in q)
    {
        Console.WriteLine($"{item.Date.ToString("yyyy-MM-dd")} {item.Amount}");
    }
}

// Define other methods and classes here
public class TotalPaymentStatistics
{
    public DateTime RegisteredAt { get; set; }
    public double TotalAmount { get; set; }
}
</pre>
此外,我还将以下示例数据存储在数据库中:

2021-01-01 | 120
2021-01-02 | 120
2021-01-03 | 120
2021-01-04 | 120
2021-01-05 | 120
2021-01-06 | 120
2021-01-07 | 120
2021-01-08 | 120
2021-01-09 | 120
2021-01-10 | 120
如何以这样的方式对此类的对象进行分组,当我传递参数时,例如5,(5-是一个时间框架,意味着我希望在整个集合中每5天接收一次汇总数据),我将收到以下结果:

2021-01-01 600
2021-01-05 600

提前感谢

您可以试试这个。假设您的dbcontext类是_context,并将DaysCount作为int类型添加到模型中进行天数计数,那么您可以编写为

_context.yourTables.GroupBy(x=>x.RegisteredAt.Date).select(t=>new TotalPaymentStatistics (){
 RegisteredAt =t.Key,
 TotalAmount =t.Sum(s=>s.TotalAmount),
 DaysCount = t.Count()
}).ToList();

普遍的做法是只使用四舍五入到最接近的值。您可以通过这种方式指定任何时间间隔。例如:

然后你可以:

var groupInterval = TimeSpan.FromDays(5);
var groups = input
      .GroupBy(x=> x.RegisteredAt.Floor(groupInterval))
      .Select(x=> 
          new 
          { 
               date = x.Key, 
               sum = x.Sum(y=> y.TotalAmount)
          });

通过指定起始班次或使用下限/上限/舍入方法,您可以稍微调整它以获得所需的组。

使用简单的分区:数据是有序的,并且至少有一个元素

static IEnumerable<List<T>> Partition<T>(List<T> input, Func<T, DateTime> DateSelector, TimeSpan partitionSize)
{
    var partitionEnd = DateSelector(input.First()).Add(partitionSize);
    var partition = new List<T>();

    foreach (var element in input)
    {
        var dt = DateSelector(element);
        if (dt >= partitionEnd)
        {
            yield return partition;
            partition = new List<T>();
            partitionEnd = dt.Add(partitionSize);
        }
        partition.Add(element);
    }
    yield return partition;
}
现场演示

结果:

日期 数量 01/01/2021 00:00:00 600 01/06/2021 00:00:00 600

void Main()
{
var items=新列表()
{
new TotalPaymentStatistics(){RegisteredAt=new DateTime(2021,1,1),TotalAmount=120},
new TotalPaymentStatistics(){RegisteredAt=new DateTime(2021,1,2),TotalAmount=120},
new TotalPaymentStatistics(){RegisteredAt=new DateTime(2021,1,3),TotalAmount=120},
new TotalPaymentStatistics(){RegisteredAt=new DateTime(2021,1,4),TotalAmount=120},
new TotalPaymentStatistics(){RegisteredAt=new DateTime(2021,1,5),TotalAmount=120},
new TotalPaymentStatistics(){RegisteredAt=new DateTime(2021,1,6),TotalAmount=120},
new TotalPaymentStatistics(){RegisteredAt=new DateTime(2021,1,7),TotalAmount=120},
new TotalPaymentStatistics(){RegisteredAt=new DateTime(2021,1,8),TotalAmount=120},
new TotalPaymentStatistics(){RegisteredAt=new DateTime(2021,1,9),TotalAmount=120},
new TotalPaymentStatistics(){RegisteredAt=new DateTime(2021,1,10),TotalAmount=120},
};
DateTime day0=项目[0]。RegisteredAt.AddDays(-1);
var q=项目
.GroupBy(x=>((int)((x.RegisteredAt.Subtract(day0.TotalDays-1)/5)))
.选择(x=>new{
x、 钥匙,
日期=第0天。添加天数(x.Key*5+1),
金额=x.Sum(y=>y.TotalAmount)
});
foreach(q中的var项目)
{
Console.WriteLine($“{item.Date.ToString(“yyyy-MM-dd”)}{item.Amount}”);
}
}
//在此处定义其他方法和类
公共类TotalPaymentStatistics
{
公共日期时间注册表数据{get;set;}
公共双重合计金额{get;set;}
}
这将给你:

2021-01-01 600


2021-01-06 600

.GroupBy(p=>p.RegisteredAt.Date).Take(nDays).选择(g=>newtotalpaymentstatistics{RegisteredAt=g.Key,TotalAmount=g.Sum(i=>i.TotalAmount))
?到目前为止您尝试了什么?是否有尝试?如果我希望它每5天分组一次怎么办?这将返回我每天分组的数据。我建议您编辑您的问题,以明确您的问题。“当我传递参数时,例如5”当然需要澄清。正如你如何为他们两个都得到600。如果5是时间框架,那么第一个框架是从1到5。是从6到10。可以使用手指索引来检查^^^,但我在哪里指定天数、时间框架?@mSwierkot我在上面的模型中进行了编辑以放置天数计数,并在查询中进行了更改以获得它。
<pre>
void Main()
{
    var items = new List<TotalPaymentStatistics>()
    {
        new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,1),TotalAmount = 120},
        new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,2),TotalAmount = 120},
        new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,3),TotalAmount = 120},
        new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,4),TotalAmount = 120},
        new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,5),TotalAmount = 120},
        new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,6),TotalAmount = 120},
        new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,7),TotalAmount = 120},
        new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,8),TotalAmount = 120},
        new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,9),TotalAmount = 120},
        new TotalPaymentStatistics(){RegisteredAt = new DateTime(2021,1,10),TotalAmount = 120},
    };
    DateTime day0 = items[0].RegisteredAt.AddDays(-1);
    var q = items
        .GroupBy(x => ((int)((x.RegisteredAt.Subtract(day0).TotalDays-1) / 5)))
        .Select(x => new {
            x.Key,
            Date = day0.AddDays(x.Key*5+1),
            Amount = x.Sum(y => y.TotalAmount)
        });
    foreach(var item in q)
    {
        Console.WriteLine($"{item.Date.ToString("yyyy-MM-dd")} {item.Amount}");
    }
}

// Define other methods and classes here
public class TotalPaymentStatistics
{
    public DateTime RegisteredAt { get; set; }
    public double TotalAmount { get; set; }
}
</pre>