如何将表格按月份分组

huangapple go评论62阅读模式
英文:

How can i group table into months

问题

A IGrouping<'a, Order>.Key { get; } 获取 IGrouping<out TKey, out TElement> 的键。
返回:
IGrouping<out TKey, out TElement> 的键。
类型:
a 是 new { int Month }

> 无法隐式转换类型 'int' 为 'System.DateTimeOffset'

这是我尝试的代码...

public class Order {
    public DateTimeOffset OrderDate { get; set; }
    public decimal Subtotal { get; set; }
}

public class MyViewModel
{
    public DateTimeOffset Month { get; set; }
    public decimal Subtotal { get; set; }
}

public interface IOrderService
{
    IEnumerable<Order> GetDataAsync();
}

public class OrderService : RepositoryBase<Order>,IOrderService
{
    public OrderService(RepositoryContext repositoryContext) : base(repositoryContext)
    {
    }

    public IEnumerable<Order> GetDataAsync()
    {
        return FindAll().OrderBy(ow => ow.OrderDate)
            .GroupBy(o => new
            { 
                   Month = o.OrderDate.Month
            })
            .Select(g => new MyViewModel
            {
                Month = g.Key.Month,// 错误出现在这里
                Subtotal =g.Sum(x => x.Subtotal)
            })
            .ToList();
    }
}

这是我的数据库
order:

[
  {"OrderDate": "2023-01-08 20:07:31.0002873", "Subtotal": 100},
  {"OrderDate": "2023-01-08 20:07:31.0002873", "Subtotal": 100},
  {"OrderDate": "2023-01-08 20:07:31.0002873", "Subtotal": 100},
  {"OrderDate": "2023-02-08 20:07:31.0002873", "Subtotal": 200},
  {"OrderDate": "2023-02-08 20:07:31.0002873", "Subtotal":200},
  {"OrderDate": "2023-03-08 20:07:31.0002873", "Subtotal": 400},
  {"OrderDate": "2023-04-08 20:07:31.0002873", "Subtotal":700}
]

这是我期望的结果

[
  {"Month": "一月", "Subtotal": 300}
  {"Month": "二月", "Subtotal": 400}
  {"Month": "三月", "Subtotal": 400}
  {"Month": "四月", "Subtotal": 700}
]
英文:

A IGrouping<'a, Order>.Key { get; }
Gets the key of the IGrouping<out TKey, out TElement>.
Returns:
The key of the IGrouping<out TKey, out TElement>.
Types:
a is new { int Month }

>Cannot implicitly convert type 'int' to 'System.DateTimeOffset'

This is what i tried...

public class Order {
    public DateTimeOffset OrderDate { get; set; }
    public decimal Subtotal { get; set; }
}

public class MyViewModel
{
    public DateTimeOffset Month { get; set; }
    public decimal Subtotal { get; set; }
}

public interface IOrderService
{
    IEnumerable<Order> GetDataAsync();
}

public class OrderService : RepositoryBase<Order>,IOrderService
{
    public OrderService(RepositoryContext repositoryContext) : base(repositoryContext)
    {
    }

    public IEnumerable<Order> GetDataAsync()
    {
        return FindAll().OrderBy(ow => ow.OrderDate)
            .GroupBy(o => new
            { 
                   Month = o.OrderDate.Month
            })
            .Select(g => new MyViewModel
            {
                Month = g.Key.Month,// error is here
                Subtotal =g.Sum(x => x.Subtotal)
            })
            .ToList();
    }
}

Here is my database
order:

[
  {"OrderDate": "2023-01-08 20:07:31.0002873", "Subtotal": 100},
  {"OrderDate": "2023-01-08 20:07:31.0002873", "Subtotal": 100},
  {"OrderDate": "2023-01-08 20:07:31.0002873", "Subtotal": 100},
  {"OrderDate": "2023-02-08 20:07:31.0002873", "Subtotal": 200},
  {"OrderDate": "2023-02-08 20:07:31.0002873", "Subtotal":200},
  {"OrderDate": "2023-03-08 20:07:31.0002873", "Subtotal": 400},
  {"OrderDate": "2023-04-08 20:07:31.0002873", "Subtotal":700}
]

Here is what am expecting

[
  {"Month": "January", "Subtotal": 300}
  {"Month": "February", "Subtotal": 400}
  {"Month": "March", "Subtotal": 400}
  {"Month": "April", "Subtotal": 700}
]

答案1

得分: 0

我不明白为什么您在视图模型中使用 DateTimeOffset 仅存储月份作为字符串。

为什么不直接在视图模型中使用字符串表示月份?

如果您确实需要使用 DateTimeOffset,请使用 g.First(),它会为您提供当前键的第一个项目。

英文:

I don't understand why you use a DateTimeOffset to store only the month as string in the viewmodel.

why not juste use a string directly for month in your viewmodel ?

if you realy need to have a DateTimeOffset use g.First(), it will give you the first item for the current key

答案2

得分: 0

o.OrderDate.Month 是一个 int。请注意,如果日期跨越多年,仅按月份分组会出现问题。建议按年和月分组,然后创建新的 DateTimeOffset

另一个问题是 Offset。源日期是否也是 DateTimeOffset 类型?如果是,可以从那里获取偏移量。这需要按照该偏移量进行分组。否则,您将需要指定一个常量偏移量作为 TimeSpan

我已将 day 设置为 1,hourminutesecond 设置为 0。请注意,对包含较少记录的分组数据进行排序更有效率。

可能也可以不按偏移量分组,然后使用 g.First(x => x.OrderDate.Offset) 取其中一个。

英文:

o.OrderDate.Month is an int. Also note that grouping only by the month number is problematic if the dates span more than one year. I would group by year and month. From this, you can then create a new DateTimeOffset.

Another problem is the Offset. Is the source date also of type DateTimeOffset? If yes you can take this offset from there. This requires grouping by this offset as well. Otherwise you will have to specify a constant offset as a TimeSpan.

public IEnumerable<MyViewModel> GetDataAsync()
{
    return FindAll()
        .GroupBy(o => new
            {
                Year = o.OrderDate.Year,
                Month = o.OrderDate.Month,
                Offset = o.OrderDate.Offset
            })
        .OrderBy(g => g.Key.Year)
        .ThenBy(g => g.Key.Month)
        .Select(g => new MyViewModel
            {
                Month = new DateTimeOffset(
                    g.Key.Year, g.Key.Month, 1, 0, 0, 0, g.Key.Offset),
                Subtotal = g.Sum(x => x.Subtotal)
            })
        .ToList();
}

I have set day to 1 and hour, minute and second to 0. Note that it is more efficient to order the grouped data containing less records.

It may also be okay not to group by the offset and then to take one with g.First(x => x.OrderDate.Offset)

答案3

得分: 0

以下是翻译好的部分:

你可以使用以下代码进行分组:

var _dds = context.Orders.OrderBy(ow => ow.OrderDate)
          .GroupBy(o => new
          {
              Year = o.OrderDate.Year,
              Month = o.OrderDate.Month
          })
          .Select(g => new MyViewModel
          {
              Month = new DateTimeOffset(DateTime.Parse(g.Key.Year + "-" + g.Key.Month + "-01")),
              Subtotal = g.Sum(x => x.Subtotal)
          })
          .ToList();
英文:

You can group by using the following code

 var _dds = context.Orders.OrderBy(ow => ow.OrderDate)
          .GroupBy(o => new
          {
              Year = o.OrderDate.Year,
              Month = o.OrderDate.Month

          })
          .Select(g => new MyViewModel
          {
              Month = new DateTimeOffset(DateTime.Parse(g.Key.Year + "-" + g.Key.Month + "-01")),
              Subtotal = g.Sum(x => x.Subtotal)
          })
          .ToList();

huangapple
  • 本文由 发表于 2023年5月10日 21:17:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/76218925.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定