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
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.
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
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.
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.
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.
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.
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.
03. januar 2011 - 17:13
#8
eller smid en sql profiler på ... eller hent
http://nhprof.com/mvh
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.
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
16. januar 2011 - 15:49
#11
svar fra mig
16. januar 2011 - 15:51
#12
I nyere 2.x kommer LINQ med NH - det er bare en separat DLL. No big deal.
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
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.
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.