Avatar billede justincase1089 Nybegynder
01. januar 2011 - 21:23 Der er 13 kommentarer og
1 løsning

LINQ or store lister

Hej Eksperter

Du har en tabel med en million entries. Tabellen har et par fields, hvoraf det ene er unikt. Programmatisk vil du nu gerne bruge LINQ (/ lambda expression) til at finde.

MyClass myClass = table.First(r => r.Id = myId);

Dette er en forsimplet problemstilling, men den illustrere fint det jeg forsøger på. Problemet er jo at "table" er en liste som allerede skal være populeret med entries fra databasen for at man kan bruge lambda expressions derpå. Det giver selvfølgelig et meget uhensigtsmæssigt overhead. Så spørgsmålet er nu hvordan jeg kan implementere funktionaliteten deri selv. Jeg har fundet flere eksempler hvor jeg får fingrene i koden nedenunder der parser ens Expression, men jeg ender hver gang med behovet for en fuldt populeret liste, og så forsvinder ideen lidt.

Så spørgsmålet er. Er der en der har et eksempel på hvordan ens LINQ expressions kan håndteres selv.

MVH
  Justin Case
Avatar billede arne_v Ekspert
01. januar 2011 - 21:53 #1
Hvis du mener LINQ to SQL så bliver den .First() pænt oversat til en SELECT TOP 1, så alt hentes ikke.
Avatar billede justincase1089 Nybegynder
01. januar 2011 - 22:24 #2
Hej Arne

Tak for kommentaren. Jeg ved ikke om jeg mener LINQ to SQL, for det er jo dødt. Lad os bare tage et andet eksempel.

List<MyClass> myClassList = table.Where(r => r.Group = "SomeGroup");

Hvor den så kun reducerer en meget lille brøkdel. Af de data der er deri. Men "table" skal stadig være populeret for at LINQ virker på listen og det er det overhead jeg gerne vil undgå

MVH
  Justin Case
Avatar billede arne_v Ekspert
01. januar 2011 - 22:53 #3
LINQ er jo ikke bare LINQ men LINQ to XXX.

For LINQ to Objects vil alle data allerede være i memory og .First() vil tage det første objekt uden at kigge på de andre.

For LINQ to SQL vil data ikke være i memory - data bliver først hentet fra databasen når der er brug for det. Og når man henter en enkelt række med .First() så bliver der udført en SELECT TOP 1 sætning mod databasen og henter derfor kun en enkelt række.

For LINQ to EF bliver data også først hentet når nødvendigt, men jeg har bare ikke checket om den laver en SELECT TOP 1, men det vil jeg tro at den gør.
Avatar billede arne_v Ekspert
01. januar 2011 - 23:28 #4
Jeg har lige kigget lidt på LINQ to EF. Det er ikke nemt at få SQL sætningen ud i alle tilfælde.
Avatar billede justincase1089 Nybegynder
02. januar 2011 - 00:08 #5
Med til historien hører, at jeg anvender NHibernate på en postgres database. I forlængelse af det du skrev ovenover må NHibernate.Linq jo være en provider, og den ser lovende ud.
Avatar billede arne_v Ekspert
02. januar 2011 - 00:54 #6
Ah. LINQ for NHibernate. :-)

LINQ for NHibernate genererer også SELECT TOP 1 for .First() d.v.s. at den også kun henter en eneste række.
Avatar billede arne_v Ekspert
02. januar 2011 - 00:55 #7
Og så er det meget nemt at få NHibernate til at vise hvad der sker bagved.

<property name="show_sql">true</property>

i din hibernate config og den outputter alle SQL sætninger den udfører til hvor nu log4net er konfiguereret til at outputte.
Avatar billede Syska Mester
03. januar 2011 - 17:13 #8
eller smid en sql profiler på ... eller hent http://nhprof.com/

mvh
Avatar billede justincase1089 Nybegynder
16. januar 2011 - 12:59 #9
Den nemmeste måde at gøre det på var faktisk bare at bruge NHibernate.Linq.dll, som giver al den funktionalitet der skal til.
Avatar billede Syska Mester
16. januar 2011 - 14:09 #10
Altså du vil have svar fra Arne.

LINQ burde være bygget ind i NH3 ... bruge du version 2? Der kommer det nemlig som en ekstern provider.

mvh
Avatar billede arne_v Ekspert
16. januar 2011 - 15:49 #11
svar fra mig
Avatar billede arne_v Ekspert
16. januar 2011 - 15:51 #12
I nyere 2.x kommer LINQ med NH - det er bare en separat DLL. No big deal.
Avatar billede Syska Mester
16. januar 2011 - 16:18 #13
#Arne
Var det ikke også det jeg skrev, altså en ekstra provider til NH. Har ikke brugt NH 2, kun læst at den i NH3 skulle være meget bedre.

Var det ikke et helt andet project hvor de så bare tog den dll med?

I 3.x har de skrevet den helt om, og der skulle være mange forbedringer i forhold til den anden version som var med i 2.x.

mvh
Avatar billede arne_v Ekspert
16. januar 2011 - 16:26 #14
Jeg har kun brugt den binære distribution, så jeg ved ikke hvordan source code er struktureret.

I den binære distribution skal man bruge 4 DLL fra Required_Bins, et antal DLL's fra Required_For_LazyLoading\Xxxx alt efter om man vil bruge lazy loading og hvilken man foretrækker (jeg plejer at bruge LinFu). Og så 1 DLL fra LINQ hvis man vil bruge LINQ.

Med LinFu er det 6 DLL uden LINQ og 7 DLL med LINQ.

Jeg har slet ikke læst noget om 3.x ændringerne, men det kan sagtens tænkes at de har omskrevet LINQ delen. Da MS kom på banen med LINQ fik alle ORM pludseligt meget travlt "so ein ding mussen wir auch haben" og måske blev tingene ikke lige designet helt optimalt.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester