LINQ - sumowanie wartości z każdego dnia i wyświetlenie w liście miesięcznej

0

Cześć witam i znów o pomoc pytam !!

Pobieram z bazy danych następującą tablicę:

Data Wartość
01.06.2022 3
01.06.2022 1
01.06.2022 1
03.06.2022 5
03.06.2022 7
03.06.2022 3
05.06.2022 5

itd. do końca miesiąca

a chcę za pomocą LINQ przekształcić ją w następującą

Data Dzień Suma Wartości
01.06.2022 środa 5
02.06.2022 czwartek
03.06.2022 piątek 15
04.06.2022 sobota
05.06.2022 niedziela 5
06.07.2022 poniedziałek

itd. do końca miesiąca

Pierwszy mój pomysł był zgrupować w LINQ dane względem dnia i sumować ale w rezultacie mają być również dni bez wartości czyli np jak w przykładzie jest 2 czerwca nie znam się na LINQ zbyt dobrze i często jak kombinuje przy pomocy pętli później okazuje się że było można do coś zrobić dużo prościej w LINQ i dlatego tutaj moje pytanie do znawców jak mam najlepiej to zrobić ? Czy LINQ ma w sobie funkcję dodawania nazwy dni do daty (że np poniedziałek)? W rezultacie też niezależnie do którego dnia mam wartości muszę mieć listę dla całego miesiąca więc np w czerwcu to będzie 30 dni ale już w lipcu 31.

Naprawdę utknąłem w miejscu i bardzo proszę o pomoc !

2

da się tu zrobić więcej LINQ np. zamieniając fora na IENumerable.Range i tam robiąc selecty itd, ale zostawiłem fora.

chyba działa ;)

public class DataWithSum
{
    public DateTime Date { get; set; }
    public int? Sum { get; set; }
    public string DayName => Date.DayOfWeek.ToString();
}

public class Data
{
    public DateTime Date { get; set; }
    public int Value { get; set; }
}

public static List<DataWithSum> ProcessData(List<Data> data)
{
    if (data.Select(x => x.Date.Month).Distinct().Count() != 1)
        throw new Exception("data should be just from 1 month");

    var firstDate = data.First().Date; // wypadałoby sprawdzić czy są dane :>
    var daysCount = DateTime.DaysInMonth(firstDate.Year, firstDate.Month);

    var output = new List<DataWithSum>();
    for (int i = 1; i <= daysCount; i++)
    {
        var date = new DateTime(firstDate.Year, firstDate.Month, i);
        output.Add(new DataWithSum { Date = date });
    }

    var groups = data.GroupBy(x => x.Date.Date).ToList(); // istotne jest to .Date.Date -  A new object with the same date as this instance, and the time value set to 12:00:00 midnight (00:00:00).

    foreach (var group in groups)
    {
        var dayToOverwrite = output.First(d => d.Date == group.Key.Date);
        dayToOverwrite.Sum = group.Sum(x => x.Value);
    }

    return output;
}

public static void Main()
{
    var data = new List<Data>
    {
        new Data { Date = DateTime.Now.AddDays(-24), Value = 35 },
        new Data { Date = DateTime.Now.AddDays(-24), Value = 15 },
        new Data { Date = DateTime.Now.AddDays(-28), Value = 4 }
    };

    var result = ProcessData(data);

    foreach (var entry in result)
    {
        Console.WriteLine($"{entry.Date} {(entry.Sum?.ToString() ?? "NULL")} {entry.DayName}");
    }
}
01.06.2022 00:00:00 NULL Wednesday
02.06.2022 00:00:00 4 Thursday
03.06.2022 00:00:00 NULL Friday
04.06.2022 00:00:00 NULL Saturday
05.06.2022 00:00:00 NULL Sunday
06.06.2022 00:00:00 50 Monday
07.06.2022 00:00:00 NULL Tuesday
08.06.2022 00:00:00 NULL Wednesday
09.06.2022 00:00:00 NULL Thursday
10.06.2022 00:00:00 NULL Friday
11.06.2022 00:00:00 NULL Saturday
12.06.2022 00:00:00 NULL Sunday
13.06.2022 00:00:00 NULL Monday
14.06.2022 00:00:00 NULL Tuesday
15.06.2022 00:00:00 NULL Wednesday
16.06.2022 00:00:00 NULL Thursday
17.06.2022 00:00:00 NULL Friday
18.06.2022 00:00:00 NULL Saturday
19.06.2022 00:00:00 NULL Sunday
20.06.2022 00:00:00 NULL Monday
21.06.2022 00:00:00 NULL Tuesday
22.06.2022 00:00:00 NULL Wednesday
23.06.2022 00:00:00 NULL Thursday
24.06.2022 00:00:00 NULL Friday
25.06.2022 00:00:00 NULL Saturday
26.06.2022 00:00:00 NULL Sunday
27.06.2022 00:00:00 NULL Monday
28.06.2022 00:00:00 NULL Tuesday
29.06.2022 00:00:00 NULL Wednesday
30.06.2022 00:00:00 NULL Thursday
0

Super dziękuję za rozwiązanie i to za całą gotową funkcję - działa rewelacyjnie, tylko jedno chyba lamerskie pytanie mam co zrobić aby dni tygodnia były po polsku ...?

3
using System;
using System.Globalization;

class Program
{
    static void Main()
    {
        var dayOfWeek = DateTime.Now.DayOfWeek;

        // aktualny język systemowy
        string dayName = DateTimeFormatInfo.CurrentInfo.GetDayName(dayOfWeek);
        Console.WriteLine(dayName);

        // wybrany język
        var dtFormatInfo = new CultureInfo("pl-PL").DateTimeFormat;
        string dayNameDe = dtFormatInfo.GetDayName(dayOfWeek);
        Console.WriteLine(dayNameDe);
    }
}

1

Jako ciekawostka, jeśli chciałbyś to zrobić za pomocą LINQ

var currentYear = DateTime.Now.Year;
var currentMonth = DateTime.Now.Month;
var daysInMonth = DateTime.DaysInMonth(currentYear, currentMonth);

var days = Enumerable.Range(1, daysInMonth).Select(dayNumber => new DateTime(currentYear, currentMonth, dayNumber));

var res = days.Select(day =>
    new DataWithSum
    {
        Date = day,
        Sum = data.Where(y => y.Date.Date == day).Sum(y => y.Value),
    });

1 użytkowników online, w tym zalogowanych: 0, gości: 1