Casablanca: LINQ

Hallo Forum,

ich habe mindestens 3 Array, die mir so "List<IEnumerable<object>>" vorliegen. Diese aray beinhaltet u.a. eine Date-Spalte (1-31 Tage) und eine Value spalte.

Aray 1 = [ {1.1.2014, 123,55}, {2.1.2014, 223,15}, {3.1.2014, 653,55}, {4.1.2014, 673,01}, ...]
Aray 2 = [ {2.1.2014, 555,33}, {3.1.2014, 243,15}, {4.1.2014, 988,55}, {5.1.2014, 979,01}, ...]
Aray 3 = [ {1.1.2014, 443,55}, {3.1.2014, 323,15}, {4.1.2014, 853,55}, {5.1.2014, 756,01}, ...]

Wie man sieht, fehlen bei z.B. Array 2 und 3 einige Tage. Ich muss nun via LINQ aus diesen Array ein Array machen, indem ich die Werte mit denselben Datum miteienader addiere, also:

Array result: [ ({1.1.2014, 123,55} + {1.1.2014, 443,55}), ({2.1.2014, 223,15} + {2.1.2014, 555,33}), ({3.1.2014, 653,55} + {3.1.2014, 243,15}), ({4.1.2014, 673,01} + {4.1.2014, 988,55} + {4.1.2014, 853,55}), ({5.1.2014, 673,01} + {5.1.2014, 756,01}), ... ]

Wie kann man dies performant erledigen?

Danke im Voraus.

  1. Hallo Forum,

    Array result: [ ({1.1.2014, 123,55} + {1.1.2014, 443,55}), ({2.1.2014, 223,15} + {2.1.2014, 555,33}), ({3.1.2014, 653,55} + {3.1.2014, 243,15}), ({4.1.2014, 673,01} + {4.1.2014, 988,55} + {4.1.2014, 853,55}), ({5.1.2014, 673,01} + {5.1.2014, 756,01}), ... ]

    Wie kann man dies performant erledigen?

    Perl-Variante: Ein Durchlauf über alle Arrays, Datum als Schlüssel im Ergebnis-Hash und += als Operator:

    {1.1.2014, 123, 55}
    {1.1.2014, 443, 55}
    ...
    ----------------------
    1.1.2014 => 566, 110

    MfG

    1. Hi,

      danke. So einfach ist es nicht. So werden die Tage, die nicht in allen Arrays vorhanden sind, nicht erfasst. Wie gesagt, da fehlen einige Tage.
      Ich habe nun mir gedacht, erst alle fehleneden Tagen in Arrays identifizieren und die einfach Mal mit 0-Werten ersetzen (z.B. bei Array 3:

      Aray 3 = [ {1.1.2014, 443,55}, {2.1.2014, 0}, {3.1.2014, 323,15}, {4.1.2014, 853,55}, {5.1.2014, 756,01}, ...] )

      Im nächsten Schritt, kann ich dann in die Werte einfach miteinender addieren.

      Gruß

      1. Hi,

        danke. So einfach ist es nicht. So werden die Tage, die nicht in allen Arrays vorhanden sind, nicht erfasst. Wie gesagt, da fehlen einige Tage.

        Achso. Ja, dann gibt ein Raster vor für die Tage, die dann lückenlos aufeinanderfolgend sind.

        Im nächsten Schritt, kann ich dann in die Werte einfach miteinender addieren.

        Iteriere über das Raster, ein Durchlauf. Vorher machst Du aus den x-Arrays EINE Datenstruktur und beim Interieren über das Raster greifst Du einfach nur in diese Datenstruktur um die Werte da rauszufischen.

        Petri Heil ;)

        1. Hi,

          danke. Was meinst du geanau. Ich muss aus x-Arrays zur Laufzeit eine Datenstruktur machen? Wie? Das kann man bestimmt auch mit LINQ erledigen können!

          Gtruß

          1. Hi,

            danke. Was meinst du geanau. Ich muss aus x-Arrays zur Laufzeit eine Datenstruktur machen? Wie? Das kann man bestimmt auch mit LINQ erledigen können!

            Ich kann Dir nur hier nur mal zeigen, wie ich das mit Perl machen würde. Zum aneinanderhängen der Arrays müssen die Referenzen aufgelöst werden, das macht der Klammerausdruck im Schleifenkopf. Aufsummiert wird über das Datum in jeweils einen Hash, die Arrays habe ich so umgeschrieben, dass Perl damit klarkommt.

              
            use strict;  
            use warnings;  
            use Data::Dumper;  
              
            my $a1 = [ ['1.1.2014', 123,55], ['2.1.2014', 223,15], ['3.1.2014', 653,55], ['4.1.2014', 673,01]];  
            my $a2 = [ ['2.1.2014', 555,33], ['3.1.2014', 243,15], ['4.1.2014', 988,55], ['5.1.2014', 979,01]];  
            my $a3 = [ ['1.1.2014', 443,55], ['3.1.2014', 323,15], ['4.1.2014', 853,55], ['5.1.2014', 756,01]];  
            #            date        x   y  
              
              
            my %res_x = ();  
            my %res_y = ();  
            foreach my $r (@$a1, @$a2, @$a3){  
                my $date = $r->[0];  
                my ($x,$y) = ($r->[1], $r->[2]);  
                $res_x{$date} += $x;  
                $res_y{$date} += $y;  
            }  
              
            print Dumper \%res_x, \%res_y;  
              
            $VAR1 = {  
                      '2.1.2014' => 778,  
                      '5.1.2014' => 1735,  
                      '3.1.2014' => 1219,  
                      '1.1.2014' => 566,  
                      '4.1.2014' => 2514  
                    };  
            $VAR2 = {  
                      '2.1.2014' => 48,  
                      '5.1.2014' => 2,  
                      '3.1.2014' => 85,  
                      '1.1.2014' => 110,  
                      '4.1.2014' => 111  
                    };  
              
            
            

            Perl ist nicht LINQ, mich hat nur das Thema herausgefordert ;)

            1. Hi,

              vielen Dank. Guter Ansatz. Danke für deine Bemühung.

              Gruß

  2. Tach!

    Wie man sieht, fehlen bei z.B. Array 2 und 3 einige Tage. Ich muss nun via LINQ aus diesen Array ein Array machen, indem ich die Werte mit denselben Datum miteienader addiere, also:

    Wenn ich mir die LINQ-Methoden anschaue, dann denke ich mir, dass die drei Mengen zunächst zu einer verbunden werden sollten. Das geht mit Concat(), was du bei drei Sequenzen (Arrays) zweimal aufrufen musst. Dann hast du eine flache Menge wie in einer Tabelle einer Datenbank. Jetzt darüber ein GroupBy() laufen lassen, das ergibt einen Wert pro Tag und für den als resultSelector ein Sum() auf die Werte anwenden.

    dedlfix.

    1. Hi,

      vielen Dank. Sehr gute Idee. Die Anweisung sieht jetzt so aus:

        
      var values = query.SelectMany(n => n).GroupBy(gr => gr.TimeStamp.Day).Select(gr => gr.Sum(g => g.DeviceDay)).ToList();  
      
      

      Da gibt es zwei Probleme:

      1. Die Tage, die nicht in allen Array vorhanden sind, tauchen merkwürigerweise nicht in der Merge-List uaf.
      2. Mein GroupBy() sollte eingentlich so aussehen;

        
      .GroupBy(gr => gr.Id, gr.MyDate.Day, gr.MyValue).Select(gr => gr.Sum(g => g.MyValue)).ToList();  
      
      

      Das geht aber nicht. Ich muss alle Felder, die im GroupBy vertreten sind, mitnehmen. Also habe ich es so versucht:

        
      .GroupBy(gr => new { gr.Id, (DateTime)EntityFunctions.TruncateTime(gr.MyDate), gr.MyValue }).Select(gr => new { gr.Sum(g => g.DeviceDay), gr.Key.DeviceId, gr.Key.TimeStamp}).toList();  
      
      

      Das klappt aber auch nicht, weil 1.: "(DateTime)EntityFunctions.TruncateTime" nicht in einem "GroupBy()" auftauschen darf und 2.: die Werte werden so nicht mehr groupiert.

      Hast eventuell eine Idee?

      Gruß

      1. Tach!

        var values = query.SelectMany(n => n).GroupBy(gr => gr.TimeStamp.Day).Select(gr => gr.Sum(g => g.DeviceDay)).ToList();

        Da gibt es zwei Probleme:

        Erstmal zum Klarstellen, arbeitest du mit Arrays oder wird aus dem LINQ-Bandwurm am Ende eine SQL-Query erstellt? Eventuell bietet es sich an, weiter vorn ein ToList() einzufügen, um aus LINQ-to-SQL/whatever rauszukommen und mit LINQ-to-Objects weitermachen zu können. Das ist dann reines C# und muss nicht nach SQL übersetzt werden. Je nach LINQ-Ausführung stehen ja auch mal mehr mal weniger Methoden(überladungen) zur Verfügung.

        1. Die Tage, die nicht in allen Array vorhanden sind, tauchen merkwürigerweise nicht in der Merge-List uaf.

        An welcher Stelle verschwinden sie denn? Zerleg doch mal die Methodenkette in ihre Einzelteile und schau dir die jeweiligen Ergebnisse an.

        1. Mein GroupBy() sollte eingentlich so aussehen;
          .GroupBy(gr => gr.Id, gr.MyDate.Day, gr.MyValue).Select(gr => gr.Sum(g => g.MyValue)).ToList();

        Wenn du einen Methodenaufruf zeigst, solltest du auch dazuschreiben, welche der überladenen Signaturen das ist. Besonders wenn man als Leser nicht weiß, von welchem Typ die Parameter sind.

        Das geht aber nicht. Ich muss alle Felder, die im GroupBy vertreten sind, mitnehmen.

        Kannst du das "geht nicht" etwas genauer beschreiben? Und was sind "alle Felder"? Ich kenne bisher nur das Datum und einen Wert, der summiert werden soll.

        Hast eventuell eine Idee?

        Wenn du mir den Anwendungsfall etwas nachvollziehbarer beschreibst, kann ich gezielter nach Lösungsmöglichkeiten suchen.

        dedlfix.

        1. Hallo,

          vielen Dank. Ich versuche das Ganze etwas genauer zu erläutern. Meine Daten sind irgenwelche Messwerte, die ich via LINQ aus einer Datenbank hole. Die Daten sind Objekte die in eine Liste gespeichert sind, also etwa so:

            
           List [  
            List1 [ {Id1, Date, Value}, {Id1, Date, Value}, {Id1, Date, Value}, {Id1, Date, Value}, ... ],  
            List2 [ {Id2, Date, Value}, {Id2, Date, Value}, {Id2, Date, Value}, {Id2, Date, Value}, ... ],  
            List3 [ {Id3, Date, Value}, {Id3, Date, Value}, {Id3, Date, Value}, {Id3, Date, Value}, ... ],  
            ...  
          ]  
            
          Id = int, Date = DateTime, Value = float  
            
          
          

          Die Ids in der jeweiligen Listen sind immer gleich. Das heißt, ich speichere jeweils alle Daten in einer Liste, die eine bestimmte Id haben. Die Gesamtliste gebe ich irgendwann Mal dann zur Weiterverarbeitung zurück.

          Nun muss ich an einer Stelle aus allen Listen (hier 3) eine Liste machen. Demnach müssen also  alle Werte(Values), die oben jeweils in einer Spalte untereinander stehen, miteinander addiert werden. Jede Liste hat die Tage z.B. 01.01.2014 bis 31.01.2014 (wenn ein Monat 31 Tage hat). Bei manchen Listen fehlen allerdings einige Tage. Der Wert(Value) bei manchen Tagen ist gleich 0. Da der Datum vom Typ DateTime ist, wird die Sache etwas schwieriger. Dies spielt nämlich an dieser Stelle keine Rolle. Zur gruppierung muss dies also zunächst entfernt werden. Ich habe das mit "(DateTime)EntityFunctions.TruncateTime" versucht, habe ich aber an dieser Stelle keinen Erfolg gehabt.

          Die Tage, die nicht in allen Arrays vorhanden sind, verschwinden bei der Gruppierung und der Summenbildung.

          &gt; Kannst du das "geht nicht" etwas genauer beschreiben? Und was sind "alle Felder"? Ich kenne bisher nur das Datum und einen Wert, der summiert werden soll.

            
          .GroupBy(gr => gr.Id, gr.MyDate.Day, gr.MyValue).  
          
          

          Das geht nicht, weil ich bei GroupBy(gr => gr.Id,...) nur eine Datenbankspalte (gr.Id) einfügen kann. Für mehrere Spalten muss man mit "new" arbeiten. In einem anonymen Objekt dar man anschent nur einfache Datenfelder verwenden und keine Methoden wie "(DateTime)EntityFunctions.TruncateTime".

          Danke nochmals.
          Gruß

      2. Moin,

        .GroupBy(gr => new { gr.Id, (DateTime)EntityFunctions.TruncateTime(gr.MyDate), gr.MyValue }).Select(gr => new { gr.Sum(g => g.DeviceDay), gr.Key.DeviceId, gr.Key.TimeStamp}).toList();

        
        >   
        > Das klappt aber auch nicht, weil 1.: "(DateTime)EntityFunctions.TruncateTime" nicht in einem "GroupBy()" auftauschen darf und 2.: die Werte werden so nicht mehr groupiert.  
          
        leider hast du nicht begründet bzw. die Fehlermeldung erwähnt, warum es nicht auftauchen darf, aber wenn überhaupt, dann müsstest du hier auch einen Membernamen vergeben (kann man nur bei Eigenschaften weglassen).  
          
        
        > ~~~c#
          
        
        > .GroupBy(gr => new { gr.Id, MyDate = (DateTime)EntityFunctions.TruncateTime(gr.MyDate), gr.MyValue }).Select(...);  
        > 
        
        

        Alternativ könntest du auch eine Zeichenfolge für den Gruppierungsschlüssel erstellen.

        .GroupBy(gr => string.Format("{0}#{1}#{2}", gr.Id, (DateTime)EntityFunctions.TruncateTime(gr.MyDate), gr.MyValue )).Select(...);

          
        Jetzt gibt es aber noch ein Problem, wo auch deddlfix schon nachgefragt hat. Programmierst du hier gegen Linq to Objects (IEnumerable) oder Linq to Whatever (IQueryable). Beim EntityFramework greift vornehmlich letzteres (also Linq to SQL). Natürlich kann man auch die Sachen miteinander vermischen, man muss sich halt nur darüber im Klaren sein. Bevor also auf dem Client Daten verarbeitet werden können, müssen sie auch vom Server zum Client übertragen werden. Daher wäre hier IQueryable performanter, weil der Server dann schon die verdichteten Ergebnisse liefert, aber man kann dann natürlich nicht die ganzen Client-Sachen nutzen (Zugriff auf Objekte im Cache vom Client-PC).  
          
        Also ich bin kein EntityFramework-Guru, soweit ich weiss hat man hier ein Datenmodel auf dem Client, welches ein Datenmodel auf Server wiederspiegelt (SQL-Tabellen). Beim Erstellen der Modelle kann man das auch umgekehrt machen, also erst im EntityFramework Modelle erstellen und diese dann auf dem Server anlegen lassen. Es werden aber nicht nur die Modelle als Werteobjekte abgebildet, sogar die Beziehungen untereinander (Navigation-Property, Fremdschlüssel etc.). Na gut, es besteht wohl zwischen den Daten auf dem Client (die Entities) und den Daten auf dem Server (Daten in den Tabellen) eine bidirektionale Beziehung, glaub ich jedenfalls. Das EntityFramework managet management ... mänätscht das für dich :)  
          
        Soll heissen, dass es vornehmlich die Linq-Anweisungen nach SQL übersetzt, zum Server schickt, die Ergebnisse abgrast und daraus wiederum Objekte im Speicher deinem Model entsprechend generiert.  
          
        Wenn die Linq-Anweisungen also zwingend auf dem Client verarbeitet werden sollen, dann holt man sich die Daten von der IQueryable-Schnittstelle durch einen Aufruf der ToList-Methode (Alle Daten werden unter Umständen vom Server zum Client transferieren + Objekte erstellen).  
          
        Sollten darin wiederum Zugriffe auf das EntityFramework erfolgen, dann werden zum entsprechenden Zeitpunkt wieder Daten vom Server geholt, um die entsprechenden Objekte zu erhalten.  
          
        So, wiedermal mehr geschrieben als ich wollte. Ok, einen noch. Wenn du Fehler bekommst, dann ist es ziemlich nützlich diesen Fehler zu beschreiben und hier wäre auch eine Unterscheidung gut, ob der Fehler wärend der Kompilierung oder der Ausführung auftritt. Der Compiler weiss ziemlich gut, ob ein Zugriff auf dieses oder jenes Objekt im entsprechenden Kontext möglich ist oder nicht. Beim EntityFramework treten die Fehler meisten wärend der Kompilierung auf und meistens besagen diese, dass dieses Objekt oder die Art und Weise wie darauf zugegriffen wird nicht auf dem Server möglich ist. Das wiederum bedeutet, dass man wieder Linq to Objects und Linq to SQL vermischt hat.  
          
        hth  
          
          
          
          
          
          
        
        
        1. Hallo Jörgen,

          vielen Dank ür die ausführliche Erläuterung.
          Nach deiner Erläuterung sieht die Abfrage nun so aus:

            
          var values = query.SelectMany(n => n).GroupBy(gr => new { gr.Id, MyDate = (DateTime)EntityFunctions.TruncateTime(gr.Date), gr.Value }).Select(gr => new { gr.Key.Id, gr.Key.MyDate, MyValue = gr.Sum(g => g.Value) });  
          
          

          Bei der Anwendung von "ToList()" auf das Ende der Anweisung wird folgender Fehler ausgestoßen:

          "values.ToList()" hat eine Ausnahme vom Typ "System.NotSupportedException" verursacht.

          Die Anweisung zur Laufzeit hat folgende Gestaltung:

          values = {System.Linq.Enumerable.WhereSelectEnumerableIterator<System.Linq.IGrouping<<>f__AnonymousType9
          <int,System.DateTime,double>,<>f__AnonymousType9<int,System.DateTime,double>>,<>f__AnonymousType9<int,System.DateTime,double>>}

          Die vorherige LINQ-Anweisung, von der ich meine Liste (query) erhalte sieht so aus:

            
          var query = (from myId in Ids  
                       select (from myTable in Table.Where(d => d.Id == myId)  
          	     where (myTable.Date.Year == MyYear && myTable.Date.Month == MyMonth)  
          	     orderby myTable.Date  
          	     select new { myTable.Id, myTable.Date, myTable.Value }) into myQuery  
          	     where myQuery.Any()  
          	     select myQuery.ToList()).ToList();  
          
          

          Meine Methode gibt ein "IEnumerable<object>" zurück. Die Fehler tauchen momenatn zur Laufzeit auf.

          Gruß

          1. Moin Casa,

            in der Doku (EntityFunctions.TruncateTime Method) steht:

            ⇒ You cannot call this function directly. This function can only appear within a LINQ to Entities query.
            ⇒ This function is translated to a corresponding function in the database.

            An dieser Stelle sind wir aber schon ausserhalb von Linq to Entities.

            Anstatt

              
            MyDate = (DateTime)EntityFunctions.TruncateTime(gr.Date)  
            
            

            sollte folgendes helfen

              
            MyDate = gr.Date.Date  
            
            

            hth

            1. Hallo Jörg,

              vielen Dank. Jetzt klappt es.Ich verstehe aber nicht, warum ich mich bei meiner LINQ-Anweisung außerhalb von Linq to Entities befinde.

              Gruß

              1. Tach!

                vielen Dank. Jetzt klappt es.Ich verstehe aber nicht, warum ich mich bei meiner LINQ-Anweisung außerhalb von Linq to Entities befinde.

                LINQ ist erst einmal nur ein Konzept, Abfragen auf verschiedene Arten von Daten in einer möglichst einheitlichen Art und Weise zu gestalten. Das ist also quasi eine Daten(bank)abstraktionsschicht, nur dass sie eben auf alle möglichen Datenquellen angewendet werden kann. Im einfachsten Fall ist die Datenquelle ein IEnumerable<T>. Komplexer wird es, wenn eine Datenbank anzuzapfen ist. Beim IEnumerable arbeitet man direkt mit den Daten, Datenbank setzt es die LINQ-Methodenaufrufe in SQL-Statements um und sendet diese zum DBMS. Das klappt nicht in jedem Fall, weswegen es bei einigen LINQ-Methoden zum NotSupported kommt.
                Bei LINQ-to-Datenbenk/oder EF werden die Methoden nicht direkt hintereinander ausgeführt, sondern sie werden analysiert, um das SQL-Statement draus zu erstellen. Erst wenn du über die Datenmenge iterieren möchtest oder ToLIST() aufrufst, wird das SQL-Statement ausgeführt und die Datensätze in den Speicher geholt (zum Beispiel als List<T> liegen sie dort). Wenn du nun weiter LINQst, arbeitest du mit den Funktionen, die auf IEnumerable<T> aufsetzen. Damit greifst du nicht mehr auf das EF zu und bist nicht mehr in der LINQ-to-EF-Umsetzung.

                dedlfix.

                1. Hi,

                  danke für die Erklärung und die Hilfe für die Lösung meines Problems.

                  Gruß

    2. Tach!

      Wie man sieht, fehlen bei z.B. Array 2 und 3 einige Tage. Ich muss nun via LINQ aus diesen Array ein Array machen, indem ich die Werte mit denselben Datum miteienader addiere, also:

      Wenn ich mir die LINQ-Methoden anschaue, dann denke ich mir, dass die drei Mengen zunächst zu einer verbunden werden sollten. Das geht mit Concat(), was du bei drei Sequenzen (Arrays) zweimal aufrufen musst. Dann hast du eine flache Menge wie in einer Tabelle einer Datenbank. Jetzt darüber ein GroupBy() laufen lassen, das ergibt einen Wert pro Tag und für den als resultSelector ein Sum() auf die Werte anwenden.

      Heute hab ich das mal so wie vorgeschlagen nachgestellt (Ausnahme: Union statt Concat). Eine Datenbank mit drei Tabellen, jede mit derselben Struktur. Einmal ID (weils es sein muss), einmal Date und einmal Integer als Felder. Da hat mir das EF logischerweise drei Entity-Types erstellt, die alle so aussahen, aber unterschiedlich hießen. Damit ich die Datensätze miteinander in eine Ergebnismenge bringen konnte, hab ich noch eine einfache Klasse dafür erstellt.

      public class Record {  
        public DateTime Date { get; set; }  
        public int Value { get; set; }  
      }
      

      Der erste Versuch sah so aus:

      List<Record> result = db.Entity1  
        .Select(entity1 => new Record {  
          Date = entity1.Date,  
          Value = entity1.Value  
        })  
        .Union(db.Entity2.Select(entity2 => new Record {  
          Date = entity2.Date,  
          Value = entity2.Value  
        }))  
        .Union(db.Entity3.Select(entity3 => new Record {  
          Date = entity3.Date,  
          Value = entity3.Value  
        }))  
        // .ToList()  
        .GroupBy(record => record.Date.Date, (date, values) => new Record { Date = date, Value = values.Sum(record => record.Value)}).ToList();
      

      Nach dem zweiten Union waren alle Datensätze in einer flachen Struktur vorhanden. Das GroupBy hat dann beim Ausführen gemeckert "The specified type member 'Date' is not supported in LINQ to Entities." Das kann also offensichtlich nicht nach SQL übersetzt werden. Also hab ich vor das GroupBy ein .ToList() eingefügt und hab damit "LINQ to Entities" verlassen. Nun hat das problemlos geklappt. Das Gruppieren und Datumsberechnen wurde wurde damit vom Client erledigt.

      Ein Nachteil dieser Methode kann sein, dass die Datenmenge gegebenenfalls recht groß wird, die vom DBMS zum Client übertragen werden und dort verarbeitet werden muss.

      Das record.Date.Date (das erste Date ist der Feldnamen, das zweite eine Eigenschaft, die den Datumsanteil eines DateTime liefert) kann gegebenenfalls zu record.Date gekürzt werden, wenn im DBMS lediglich Datümer ohne Zeiten abgelegt sind. Dann ist der Time-Teil ja immer 00:00:00 und es klappt auch ohne das eingefügte ToList().

      dedlfix.

      1. Hi,

        vielen Dank. Zwei Fragen Hätte ich dazu.

        1. Ich habe bei der gruppierung von Date.Date nun ein Problem, dass ich jetzt die Daten zwar problemlos gruppiern kann, die zeiten, die ich bereits dadurch abgeschniten habe (01.01.2014 16:10:25 wurde zu 01.01.2014 00:00:00), stehen mir bei der Mitnahme der Daten (bei dir new Record) nicht mehr zur Verfügung. Diese müssen aber hinterher bei mir angezeigt werden.

        2. Was sind (date, values) hier zu beeuten? Sollte da nicht ein "new" hin?

          
        .GroupBy(record => record.Date.Date, (date, values) => new Record { Date = date, Value =  
        
        

        Gruß

        1. Tach!

          1. Ich habe bei der gruppierung von Date.Date nun ein Problem, dass ich jetzt die Daten zwar problemlos gruppiern kann, die zeiten, die ich bereits dadurch abgeschniten habe (01.01.2014 16:10:25 wurde zu 01.01.2014 00:00:00), stehen mir bei der Mitnahme der Daten (bei dir new Record) nicht mehr zur Verfügung. Diese müssen aber hinterher bei mir angezeigt werden.

          Das geht aber nicht. Die Gruppe fasst mehrere Datensätze zu einer Ergebniszeile zusammen. Da kann dann nur noch ein Wert drinstehen. Es können also nicht alle Zeiten in die Ergebnismenge kommen. Du kannst aber eine Aggregate-Funktion anwenden, also sowas wie das Sum(). Damit kannst du zum Beispiel den kleinsten Wert, den größten Wert, oder auch eine Stringwurst aus allen zusammengehängten Werten ins Ergebnis nehmen. Beispiel siehe verlinkte Handbuchseite zu GroupBy().

          1. Was sind (date, values) hier zu beeuten? Sollte da nicht ein "new" hin?
            .GroupBy(record => record.Date.Date, (date, values) => new Record { Date = date, Value = ...

          Auch das ist in dem Handbuch-Beispiel zu sehen. Das ist ein Lambda-Ausdruck, der zwei Werte entgegennimmt. An der Stelle wird eine Funktion erwartet, die zwei Parameter haben möchte. Die muss man dann beim Lambda-Ausdruck auf die gezeigte Weise klammern. Man braucht da ja zum einen das Gruppierkriterum und zum anderen die Datemenge zu diesem Kriterium.

          dedlfix.