[C# / LINQ] Group by en Max

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
SQL:
1
2
3
4
SELECT * FROM Data 
WHERE Ticket IN 
    ( SELECT MAX(Ticket) FROM Data
         GROUP BY DATEPART(day, TicketDate), DATEPART(month, TicketDate), DATEPART(year, TicketDate) )


Ik gebruik nu bovenstaande query om data uit mijn database op te vragen. Ik ben nu met Linq bezig en wil graag de query omzetten naar een Linq equivalent. Let op: Niet Linq to Sql, maar Linq. De data is nu een List<CustomObject> collection in het geheugen.

Ik heb het onderstaande reeds bedacht; voor het GROUP BY <unique day> gedeelte heb ik echter geen duidelijk idee. Commentaar op de rest van de query of hoe ik dit anders in c# zou kunnen aanpakken in natuurlijk ook welkom.

C#:
1
2
3
4
5
6
7
8
9
10
from transaction in _allTransactions
where
(

from transaction in _allTransactions
//Group by per unieke dag.
select transaction.Ticket ).Max();

).Contains(transaction.Ticket)
select transaction

Acties:
  • 0 Henk 'm!

  • mOrPhie
  • Registratie: September 2000
  • Laatst online: 20:15

mOrPhie

❤️❤️❤️❤️🤍

GroupBy
http://msdn.microsoft.com...arp/aa336754.aspx#simple1

C#:
1
2
3
(from t in _allTransactions 
 group t by c.TicketDate into newGroup
 select newGroup.Ticket).Max()


Aangezien er maar 1 waarde wordt teruggegeven hoeft het overigens geen contains te zijn.
En je wilt er wellicht een "ToShortDate" van maken, om van de tijd af te zijn. :)

[ Voor 54% gewijzigd door mOrPhie op 12-12-2008 19:53 ]

Een experimentele community-site: https://technobabblenerdtalk.nl/. DM voor invite code.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Het is niet één waarde dat ik probeer terug te geven. Voor _elke_ unieke dag moet het hoogste ticket nummer worden terug gegeven. De buitenste query haalt dan de transacties op met die ticket nummers. Misschien is het makkelijker als ik de queries uit elkaar haal. Het onderstaande compileert nog prima; het groeperen lukt echter totaal niet.

C#:
1
2
3
4
5
6
7
8
9
            long[] tickets =
                    ( from t in _allTransactions
                      //group t by t.TicketDate into newGroup
                      select t.Ticket ).ToArray();
            
            TransactionObject[] transactions =
                    ( from transaction in _allTransactions
                     where tickets.Contains( transaction.Ticket )
                      select transaction ).ToArray();


Het onderstaande, naar bovenstaande link compileert wel. Het geeft echter alle ticket nummers terug en niet enkel de max per unieke dag. Ik heb ook het idee dat by t.Ticket niet correct is.

C#:
1
2
3
4
5
6
7
8
9
            var tickets =
                    ( from t in _allTransactions
                      group t by t.Ticket into g
                      select new { Day = g.Key, Transaction = g.Max() } );

            foreach ( var day in tickets )
            {
                Console.WriteLine( day.Transaction.Ticket );
            }

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Verwijderd schreef op vrijdag 12 december 2008 @ 21:05:
Het is niet één waarde dat ik probeer terug te geven. Voor _elke_ unieke dag moet het hoogste ticket nummer worden terug gegeven. De buitenste query haalt dan de transacties op met die ticket nummers.
Je wilt dus een groupwise-maximum doen in Linq, en je hebt als extra informatie dat ticket een oplopend uniek id is?
Misschien is het makkelijker als ik de queries uit elkaar haal. Het onderstaande compileert nog prima; het groeperen lukt echter totaal niet.

C#:
1
2
3
4
            long[] tickets =
                    ( from t in _allTransactions
                      //group t by t.TicketDate into newGroup
                      select t.Ticket ).ToArray();
Ik zou aan iets denken als (ongetest, ik heb hier nu even geen c#!):
C#:
1
2
3
4
            TransactionObject[] transactions =
                    ( from t in _allTransactions
                      group t by t.TicketDate into newGroup
                      select newGroup.OrderBy(g=>g.Ticket).Last()).ToArray();

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Dat is correct. De klasse TransactionObject bevat een aantal automatic properties waaronder:

C#:
1
2
        public long Ticket { get; set; }
        public DateTime TicketDate { get; set; }


Ticket is uniek voor ieder object en is oplopend (i.e. een hoger ticket nummer is een latere transactie. TicketDate bevat een specifieke datum+tijd voor de transactie. B.v. 12 december 2008 15:43:12.

Je code klinkt logisch, enkel dan t.TicketDate vervangen door t.TicketDate.Date aangezien ik wil groeperen per unieke dag. Een snelle test laat zien dat het nog niet helemaal goed gaat. Ik moet morgen nog maar even verder debuggen en kijken waar het precies verkeerd gaat. Linq debuggen is wel wat lastiger zie ik al :)

edit: Te snel gekeken; volgens mij loopt de query perfect. Morgen maar wat nauwkeuriger bestuderen. Alvast bedankt iig.

[ Voor 7% gewijzigd door Verwijderd op 12-12-2008 23:24 . Reden: aanvulling ]