LINQ group-by and then display datetime for (dd mmm)

﹥>﹥吖頭↗ 提交于 2020-01-05 10:16:05

问题


I want Linq to group by date but display in text

here is my code

var groups = _uow.Orders.GetAll()
            .Where(x => x.Created > baselineDate)
            .GroupBy(x => x.Created.ToString("yyyy-MM-dd"));

var orders = new
        {
            Day = groups.Select(g => g.Key).ToArray(),
            Total = groups.Select(g => g.Sum(t => t.Total)).ToArray(),
        };

the result is (not good to put in label of graph)

 {"Day": [2, 3, 4, 5], "Total": [9999.00, 9999.00, 9999.00, 9999.00] }

But i want this (Monthly)

"Day": ['Jan', Feb', 'Mar', 'Apr'], "Total": [9999.00, 9999.00, 9999.00, 9999.00] }

Or Daily

"Day": ['Jan 1', 'Jan 2', 'Jan 3', 'Jan 4'], "Total": [9999.00, 9999.00, 9999.00, 9999.00] }

Please advice me for DateTime.ToString() that i can play with.

Thank you all.


回答1:


Thank you all for helping. I found the answer.

add

.AsEnumerable()

AND

 .GroupBy(x => x.Created.ToString("MMM d"));

here is full code

var groups = _uow.Orders.GetAll()
            .Where(x => x.Created > baselineDate)
            .AsEnumerable()
            .GroupBy(x => x.Created.ToString("MMM d"));

        var orders = new
        {
            Day = groups.Select(g => g.Key).ToArray(),
            Total = groups.Select(g => g.Sum(t => t.Total)).ToArray(),
        };



回答2:


This question describes how to convert a date time to the string name of the month.

EDIT: for EF, we have to pull everything into memory before doing any string logic:

var orders = _uow.Orders.GetAll()
    .Where(x => x.Created > baselineDate)
    // pull into memory here, since we won't be making the result set any smaller and
    // we want to use DateTime.ToString(), which EF won't compile to SQL
    .AsEnumerable()
    // this will group by the whole date. If you only want to group by part of the date,
    // (e. g. day or day, month), you could group by x => x.Date.Month or the like
    .GroupBy(x => x.Date)
    .Select(g => new {
        // or use just "MMM" for just the month
        Dates = g.Select(g => g.Key.ToString("MMM d")).ToArray(),
        Total = ...
    });



回答3:


You need to use functions that EF can understand and translate to SQL, such as EntityFunctions.TruncateTime. Here is your updated code:

var groups = _uow.Orders.GetAll()
            .Where(x => x.Created > baselineDate)
            .GroupBy(x => EntityFunctions.TruncateTime(x.Created));

Then use the string formatting just in the output, but make sure you're doing it after the value has been returned to .Net, using AsEnumerable to switch to Linq-to-Objects:

var orders = new
        {
            Day = groups.Select(g => g.Key)
                        .AsEnumerable()
                        .Select(x => x.ToString("MMM d"))
                        .ToArray(),
            Total = groups.Select(g => g.Sum(t => t.Total)).ToArray(),
        };


来源:https://stackoverflow.com/questions/17476542/linq-group-by-and-then-display-datetime-for-dd-mmm

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!