[C#] 2 LINQ statements combineren naar 1

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • DarthDavy
  • Registratie: Januari 2007
  • Laatst online: 06-06 16:12

DarthDavy

Excellent!

Topicstarter
Ik heb het volgende stukje code

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
            DAL myDAL = new DAL();
            List<BusinessObject> myBusinessObjects = myDAL.GetBusinessObjects();
            var myUniqueStrings = (from bo in myBusinessObjects
                                  where string.IsNullOrEmpty(bo.myString) == false
                                  select bo.myString).Distinct();
            foreach (string uniqueString in myUniqueStrings)
            {
                var myUniqueBOs = from bo in myBusinessObjects
                                  where bo.myString == uniqueString
                                  select bo;
                Dictionary<string, IEnumerable<BusinessObject>> myDictionary = new Dictionary<string,IEnumerable<BusinessObject>>();
                myDictionary.Add(uniqueString, myUniqueBOs);
            }


Ik ben er vrij zeker van dat ik de foreach kan elimineren en de 2 LINQ statements in 1 schrijven om zo de dictionary op te bouwen. Ik ben het nu al een tijdje aan het proberen, maar het lukt me maar niet. Ik mis iets waardoor ik een Dictionary van strings met een lijst van BusinessObjects kan opbouwen. Het lukt me wel om een Dictionary van strings met een BusinessObject kan opbouwen, maar dan krijg ik natuurlijk fouten door het toevoegen van duplicate keys aan de string kant.

Iemand de oplossing? Lijkt me wel een leuke LINQ uitdaging :P

Bier zonder alcohol is zoals een BH aan de wasdraad: het beste is eruit


Acties:
  • 0 Henk 'm!

Verwijderd

Kun je niet iets met de GroupBy en de ToDictionary?

Even uit het blote hoofd:
C#:
1
2
3
4
5
6
DAL myDAL = new DAL();
List<BusinessObject> myBusinessObjects = myDAL.GetBusinessObjects();
var myUniqueStrings = ( from bo in myBusinessObjects
                        where string.IsNullOrEmpty( bo.myString ) == false
                        group bo by bo.myString into gr
                        select gr).ToDictionary(g => g.Key);

[ Voor 6% gewijzigd door Verwijderd op 10-06-2009 11:15 . Reden: typo's ]


Acties:
  • 0 Henk 'm!

  • DarthDavy
  • Registratie: Januari 2007
  • Laatst online: 06-06 16:12

DarthDavy

Excellent!

Topicstarter
Aha. De ToDictionary had ik al, maar ik miste de group by clause in my LINQ query. Thanks.

Bier zonder alcohol is zoals een BH aan de wasdraad: het beste is eruit


Acties:
  • 0 Henk 'm!

Verwijderd

BTW, eerst een lijst van business objecten ophalen (met je DAL) en dan vervolgens nog een select doen ziet er op het eerste gezicht niet echt optimaal uit. Is je DAL niet een betere plek voor deze query?

Acties:
  • 0 Henk 'm!

  • DarthDavy
  • Registratie: Januari 2007
  • Laatst online: 06-06 16:12

DarthDavy

Excellent!

Topicstarter
Nee, want die lijst van objecten zijn al een stuk eerder opgehaald en er zijn ook al andere operaties op gebeurd alvorens ze naar een dictionary moeten geconverteerd worden.

Ik kon natuurlijk ook een nieuwe select naar de database gaan schrijven in de DAL, maar dan ga ik een keer naar de database voor iets dat ik al beschikbaar heb in het geheugen.

Bier zonder alcohol is zoals een BH aan de wasdraad: het beste is eruit


Acties:
  • 0 Henk 'm!

  • mOrPhie
  • Registratie: September 2000
  • Laatst online: 18-09 15:41

mOrPhie

❤️❤️❤️❤️🤍

Wat lamaketta bedoelt is dat je een Distinct en een "IsNullOrEmpty" doet op items in een List. Niet op iets wat IQueryable is. Hierdoor wordt deze operatie duur en kan bij veel items trager worden. Dit aan een query op de database overlaten zou juist veel efficienter zijn.

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


Acties:
  • 0 Henk 'm!

Verwijderd

mOrPhie schreef op woensdag 10 juni 2009 @ 14:20:
Wat lamaketta bedoelt is dat je een Distinct en een "IsNullOrEmpty" doet op items in een List. Niet op iets wat IQueryable is. Hierdoor wordt deze operatie duur en kan bij veel items trager worden. Dit aan een query op de database overlaten zou juist veel efficienter zijn.
Ik weet niet of je per definitie kunt zeggen dat deze operatie nu duur is. Je DB doet er immers bij veel items ook langer over. Volgens mij is het nog altijd sneller om een operatie te doen op iets wat je toch al in geheugen hebt dan een extra roundtrip naar je DB te maken. En aangezien DarthDavy aangeeft dat die list toch al in memory zit (omdat deze wrsch eerder nodig is) kun je het zo goed op de in-memory list doen.

Feit is wel dat door IQueryable te gebruiken je het aan .NET overlaat om de juiste Linq-provider erbij te trekken. En wanneer je toevallig op een IQueryable bezig bent waar een Linq-to-Sql provider bij hoort ben je inderdaad sneller uit omdat deze je Linq query naar SQL zal vertalen en je dan voorkomt dat je eerst allemaal data uit je db je app in trekt om hier vervolgens een query op uit te voeren.

Maar meten is weten dus er valt eigenlijk niets zinnigs over performance te zeggen totdat je de verschillen hebt gemeten!

Acties:
  • 0 Henk 'm!

  • mOrPhie
  • Registratie: September 2000
  • Laatst online: 18-09 15:41

mOrPhie

❤️❤️❤️❤️🤍

Verwijderd schreef op woensdag 10 juni 2009 @ 15:13:
[...]

Ik weet niet of je per definitie kunt zeggen dat deze operatie nu duur is.
Per definitie niet nee. Maar in veel gevallen wel. Wat je zegt, meten is weten. Echter, als het aantal items in die lijst max 100 is en de operatie gebeurd maar sporadisch, dan is er niet eens een reden om naar de performance te kijken. :)

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

Pagina: 1