Linq und Anonyme Objekte
Casablanca
- datenbank
0 dedlfix0 Casablanca0 dedlfix0 Casablanca0 dedlfix0 Casablanca0 dedlfix
Hallo Forum,
ich habe eine einfache LINQ-Anweisung, die mir die Daten zwischen zwei Tagen (z.B. 12.03.2015 06:50:11 und 13.03.2015 05:10:01) als eine Liste der anonymen Objekten liefert.
var query = from d in _db-meineTabelle.Where(x => x.datum > firstDate && x.datum < secondDate)
select new { d.datum, d.Id, d.plz }
Die Liste: [
[12.03.2015 06:50:11, 1, 12345],
[12.03.2015 06:51:20, 2, 23478],
[12.03.2015 06:52:12, 3, 98765],
[12.03.2015 06:52:45, 4, 12378],
[12.04.2015 06:53:10, 5, 76345],
[13.03.2015 05:10:01, 6, 12345],
[13.06.2015 06:51:20, 7, 23478],
[13.07.2015 06:52:12, 8, 98765],
[13.08.2015 06:52:45, 9, 12378],
[13.09.2015 06:53:10, 10, 76345],
]
Ich suche nun einen einfachen Weg, in dem resultierten Objekt und an der Stelle, wo das erste Datum endet und das zweite anfängt, ein null-Objekt hinzuzufügen:
Die Liste: [
[12.03.2015 06:50:11, 1, 12345],
[12.03.2015 06:51:20, 2, 23478],
[12.03.2015 06:52:12, 3, 98765],
[12.03.2015 06:52:45, 4, 12378],
[12.04.2015 06:53:10, 5, 76345],
[null, null, null],
[13.03.2015 05:10:01, 6, 12345],
[13.06.2015 06:51:20, 7, 23478],
[13.07.2015 06:52:12, 8, 98765],
[13.08.2015 06:52:45, 9, 12378],
[13.09.2015 06:53:10, 10, 76345],
]
Hat jemand eine Idee, wie man dies bewerkstelligen kann, ohne dass man die Liste umfüllen muss?
Gruß
Tach!
Ich suche nun einen einfachen Weg, in dem resultierten Objekt und an der Stelle, wo das erste Datum endet und das zweite anfängt, ein null-Objekt hinzuzufügen:
Ich behaupte mal, das geht (so) nicht. Die Anzahl der Datensätze in der Ergebnismenge steht nach dem Where *) fest. Das Select kann weder was hinzufügen, noch etwas entfernen. Nur umformen kann es. Und dies kann es nur mit dem aktuellen Datensatz. Es kann nicht in die Zukunft schauen. Ein Blick in die Vergangenheit wäre mit einer außerhalb gespeicherten Variable möglich. Aber das bringt dir nichts, weil das Select keine zwei Datensätze zurückgeben kann.
Hat jemand eine Idee, wie man dies bewerkstelligen kann, ohne dass man die Liste umfüllen muss?
Es geht, wenn du statt des Select die aus dem Where herauskommende Menge einem foreach übergibst. In dessen Body werden die Datensätze umgeformt und in einer vorher erstellten Liste abgelegt. Dabei kannst du nun auch in die Vergangenheitsvariable schauen (oder alternativ in das letzte Element der Liste) und bei einem Datumswechsel erst der Liste einen null-Datensatz anhängen und dann den richtigen.
*) Warum mixt du denn da die Syntax? Es geht zwar, die LINQ-Schreibweise und den funktionalen Ansatz zu mischen, aber konsistent sieht anders aus.
dedlfix.
Hi,
vielen Dank für deine Antwort. Ja das habe ich mir gedacht, dass dies nicht ohne weiteres machbar wäre. Da muss ich mir also etwas einfallen lassen.
Worauf bezieht sich dein letzter absatz ( *) )? Was ist da gemixt worden? Wie sieht die korrekte Schreibweise aus?
Gruß
Tach!
Worauf bezieht sich dein letzter absatz ( *) )? Was ist da gemixt worden? Wie sieht die korrekte Schreibweise aus?
Auf das Where im ersten Satz meiner Antwort. Das war eine Fußnote. Das da ist jedenfalls deine Query. Den Syntaxfehler im Tabellennamen ignorier ich, das ist ja nur ein Beispiel.
var query = from d in _db-meineTabelle.Where(x => x.datum > firstDate && x.datum < secondDate) select new { d.datum, d.Id, d.plz }
Es gibt jedenfalls die LINQ-Syntax, die an SQL angelehnt ist und neue Schlüsselwörter in C# eingeführt hat. Und man kann auch ganz darauf verzichten und alles mit geketteten Funktionen machen.
from datensatzalias in datenquelle where datensatzalias.eigenschaft == irgendwas select new { datensatzalias.eigenschaft, datensatzalias.andere_eigenschaft }
datenquelle .Where(datensatzalias => datensatzalias.eigenschaft == irgendwas) .Select(alias => new { alias.eigenschaft, alias.andere_eigenschaft})
So sehen die beiden Ansätze aus, wenn man sie nicht mischt. Zu beachten ist, dass im ersten Beispiel der datensatzalias für die gesamte Query gilt. Im zweiten hat jede Methode (hier Where und Select) einen selbständigen Lambda-Ausdruck und die dafür verwendete Variable ist ebenfalls unabhängig von allen anderen Variablen im Code. Damit kann man die Kette auch auseinanderpflücken und in Schritten, auch abhängig von anderen Laufzeitbedingungen, nach Bedarf recht einfach zusammenstellen
dedlfix.
Hi,
danke. Sehr hilfreich. Das Problem ist nur, dass bei dem "Methoden"-Ansatz, also Where().Select(), immer nach einer group- oder select-Klausel verlang wird. Aus diesem Grund leite ich mich manchmal dazu, die Sachen miteinander zu vermischen. Faulheit eben.
Gruß
Tach!
Das Problem ist nur, dass bei dem "Methoden"-Ansatz, also Where().Select(), immer nach einer group- oder select-Klausel verlang wird.
Dann machst du was verkehrt. Gruppieren muss man nur, wenn man was zu gruppieren hat. Select nimmt man, um das Ergebnis umzuwandeln. Wenn man mit dem Datensatz zufrieden ist, so wie er in der Datenquelle steht, dann geht das auch ohne.
dedlfix.
Hi,
eine einface Abfrage. Beispiel:
var query = from result in _db.TBL.Where(w => w.ID == Id).Select(s => s.ID);
Hier wird, wie gesagt, nach einer group oder select-Kluasel verlangt. Ich weiß nicht, wie man das hier anders schreiben sollte.
Gruß
Tach!
var query = from result in _db.TBL.Where(w => w.ID == Id).Select(s => s.ID);
Hier wird, wie gesagt, nach einer group oder select-Kluasel verlangt. Ich weiß nicht, wie man das hier anders schreiben sollte.
Das from ist wieder Query-Syntax und damit ist der Code wieder ein Gemisch aus beiden Ansätzen. Zudem ist ein from allein ungültige Query-Syntax. Diese verlangt mindestens from und select.
So wie du das schreibst, bekommt das from als Datenquelle das Ergebnis aus dem Teilstück _db.TBL.Where(w => w.ID == Id).Select(s => s.ID). Und was soll es damit nun machen? Der Satz kein Verb. "Von dieser Datenquelle" heißt der Ausdruck insgesamt. Richtig wäre sowas wie: "Von dieser Datenquelle selektiere irgendwas."
So ist es rein funktional: [code]var query = _db.TBL.Where(w => w.ID == Id).Select(s => s.ID); [/code]
Und das ist die Schreibweise in Query-Syntax: [code]var query = from d in _db.TBL where d.Id == Id select d.Id; [/code]
dedlfix.
Hi,
vielen danke. Verstanden.
Gruß