prototype schreef op maandag 14 januari 2008 @ 11:26:
Even snel tussendoor EfBe, ik weet niet hoe het met jou zit, maar ik geniet zeer van deze discussie

en zou dit dan graag ook voort willen zetten. Ik weet niet hoe jij erover voelt, want ik vermoed dat dit een ellenlange discussie gaat worden, en zou dan ook een mod willen vragen om dit te splitten aangezien het behoorlijk OT is geworden tov de TS post, leerzaam wel

.
Nou, een discussie waarbij het een herhaling van zetten wordt is niet meer zo aan me besteed

Momenteel ben ik even bezig met m'n minor opdracht, en van wat je als laatste hebt gepost heb ik veel op aan te merken nog en zou dat graag nu willen doen, maar 'k heb een deadline dus dat hou je van me tegoed, hopelijk kom ik er vandaag nog aan toe.
Veel op aan te merken? Wat valt er op aan te merken? _ALLES_ in linq is een sequence, niet een set. Een sequence is wel een set, maar een set is geen sequence. Als je Linq gaat beschouwen als set based, dan MOET je dus de operaties kunnen uitvoeren zonder terug te vallen op sequence-eigenschappen, en sorry, maar dat kan niet altijd. Het is om deze reden dat ik uberhaupt nog heb gereplied: mensen moeten doorhebben dat Linq sequence oriented is, en dus dat linq werkt omdat het met sequences werkt en niet met sets, m.a.w.: het bouwt op de eigenschap dat een sequence een volgorde heeft en dat heeft een set nu eenmaal niet.
In a nutshell is mijn punt ook geweest dat doordat je een sequence equivalent kan uitdrukken in een set, alle operaties waarvan jij nu zegt dat ze alleen weggelegd zijn voor sequences, ook toepasbaar zijn op de equivalente set notatie van de sequence. Wat ik in feite hiermee zeg is dat het even setgebaseerd is als dat het sequencegebaseerd is. Daar heb ik dan ook alle afleidingen er voor bij geleverd.
Als het set-gebaseerd is, dan moet je middels set algebra kunnen beschrijven hoe Reverse werkt op een willekeurige set van orders gesorteerd op order.Customer.Country. Dat gaat je niet lukken.
Evenals ElementAt(n). Het is nl. zo dat je ElementAt(n) alleen kunt uitvoeren wanneer je de input beschouwt als een sequence, want je doorloopt de sequence tot element n. Een set heeft geen sequentiele consumer, enumerator.
Wel wil ik snel inhaken op:
[...]
Het voorbeeld dat je hier plaatst heb ik reeds behandeld in mijn voorgaande post (inclusief wiskundige afleiding).

Nee, jouw voorbeeld doet een aanname die niet opgaat in mijn voorbeeld.
En zoals je ook in de screenshots ziet krijg ik bij mijn takewhile 2 resultaten terug ipv 4, en dat is bewerkstelligd mbv quantorpredicaten. Vanzelfsprekend zou je zonder die non-existentiele icm existentiele quantor 4 resultaten terugkrijgen. Hier hou je dus geen rekening bij jouw uitleg over 'het probleem'

.
Jij moet een aparte set erbij betrekken die een sequence formuleert. Sorry, maar dat gaat niet op. In mijn voorbeeld heb ik die sequence niet en dan lukt jouw voorbeeld dus niet. Tja, ik kan ook roepen dat ik het resultaat in een temptable dump en met een cursor het geheel eruit haal, maar dat was niet het punt, het punt was dat met louter set operaties ik die elementen er niet uitkrijg. Jij hebt een extra set nodig, N1, en OOK nog de aanname dat de elements in de resultset met een oplopende id zijn gerangschikt. Wat als ik GUIDs als key gebruik in mijn Order entity ?
[...]
Sorry, ik snap even niet wat je bedoelt met dat hier iets flawed aan is. De id column hier is niets anders dan de positie van het element in de sequence, en wanneer we een sequence gaan beschrijven als zijnde een functie/projectie/set van 2-tuples, dan
moet de index veld vanzelfsprekend continu oplopend zijn vanaf 0 (of 1 zoals ik nu doe omdat dit conform is aan Z conventie) (dat is bij een List<T> toch ook niet anders?

).
Jij doet aannames en zet je test zo op dat in JOUW geval het geheel werkt. Maar wat je op je studie wellicht hebt meegekregen is dat je zo juist niet het probleem moet benaderen. Je moet kijken wanneer je NIET met set operaties een TakeWhile kunt uitvoeren. Als ik jouw N1 tabel weghaal (want ik heb bv 10 miljoen rijen in numbers) en de rows zijn na projectie niet gesorteerd op 'id', hoe werkt TakeWhile dan?
Als je kijkt hoe linq werkt intern is het heel simpel te zien:
sequence.ExtensionMethod(parameters).ExtensionMethod(parameters)
.ExtensionMethod(parameters).ExtensionMethod(parameters)....ExtensionMethod(parameters);
Dat is een linq query. Iedere extension method levert een nieuwe sequence op, waarop de volgende extension method wordt uitgevoerd. Kijk maar naar de Queryable extension method documentatie. Die praten niet over sets hoor, maar puur over sequences.
Ik beweer niet dat een sequence geen set is, ik zeg dat als je linq als set-oriented gaat beschouwen, je dus met setoperaties een linq query kunt beschrijven, maar dat kan niet altijd, alleen in een subset van de linq methods kan dat.
Last, LastOrDefault, TakeWhile, Reverse, SkipWhile, het zijn operaties waarbij een of meerdere queries te formuleren zijn die niet in SQL / set operaties zijn uit te drukken. ElementAt(n) kan eventueel nog met een paging trick: ElementAt(n) == Get page n of size 1. Echter, paging is het sequentieel een set consumeren, door het veronderstellen van een volgorde. Idem als Take(n).
Bv als ik doe: Take(10) op Customers gejoined met orders.
SELECT TOP 10 FROM Customers C INNER JOIN Orders O ON C.CustomerID = O.CustomerID
dan zegt dit helemaal niks: het is niet gedefinieerd welke 10 customers hier geselecteerd worden, of dat er uberhaupt 10 geselecteerd worden. Aangezien Customer - Order 1:n is, is de kans zeer groot dat ik 10 keer dezelfde customer terugkrijg in mn set. En welke dat is is ook niet gedefninieerd.
Wat ik dus moet doen is het toevoegen van een order EN het toevoegen van een operatie om duplicate projection rows uit te filteren, bv DISTINCT. Echter in Linq zijn dit aparte sequence operaties. In een set oriented taal zijn dat parameters van 1 operatie (de projection).
Met de extension method Queryable.ThenBy zie je het karakter van de sequence.ExtensionMethod()... methodiek: er zit een volgorde in hoe de operaties worden uitgevoerd. Als ik op 2 columns wil sorteren, kan ik niet beginnen met ThenBy(). Het zijn aparte operaties op de sequences, het resultaat van 1 operatie is de source van de ander en wel op een sequentiele manier: de source wordt sequentieel doorlopen.
Maar goed, ik heb hier genoeg tijd aan besteed nu. Als jij hier verder nog tijd aan wil verdoen met het aantonen dat Linq set oriented is, dan moet je dat vooral doen. Ik zie je Reverse, Last, SkipWhile en TakeWhile SQL code over een set van Orders gesorteerd op Customer.Country, met Order.ID een GUID met spanning tegemoet.

(En ik denk Microsoft ook, want op dit moment doet Linq to Sql niets met deze methods om de redenen die ik hierboven geschetst heb. Let wel: queries moeten altijd werken, dus niet alleen wanneer ze toevallig samenvallen met een cleanroom opstelling zoals de jouwe die toevallig wel werkt.