Announcement

Collapse
No announcement yet.

Linq Abfrage mit Group und Sum

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Linq Abfrage mit Group und Sum

    Hallo,

    ich bin gerade mal wieder am Verzweifeln ...

    Folgende Abfrage möchte ich als eine Linq-Query schreiben:
    Code:
    SELECT d.artikelid AS ArtikelNr, d.Bezeichnung_deutsch AS Bezeichnung,b.Anzahl AS Kontraktmenge, Sum(e.Anzahl) AS AbgerufeneMenge, b.Einzelpreis, b.Bemerkung, c.Firma_Standort
    FROM tblkontrakt AS a
    JOIN tblkontrakteinzelheiten AS b ON a.KontraktNummer = b.KontraktNummer
    JOIN tblstandort AS c ON a.KundeID = c.StandortID
    JOIN tblartikel AS d ON b.ArtikelID = d.ArtikelID
    LEFT JOIN tblbestelleinzelheiten AS e ON e.KontraktNummer = a.KontraktNummer
    AND e.ArtikelID = d.ArtikelID
    JOIN tblbestellung f ON f.BestellID = e.BestellID
    WHERE a.kontraktnummer = ?contractnumber
    GROUP BY d.artikelid, c.Firma_Standort, e.kontraktnummer, d.Bezeichnung_deutsch, b.Anzahl, b.KontrakteinzelheitenID, a.LaufzeitBeginn, a.Laufzeitende, b.Einzelpreis, b.Bemerkung

    So habe ich es versucht, allerdings gibt es zum einen Probleme mit den Joins ... und zum anderen würde ich ja auch nur zwei (Spalten)Werte zurück erhalten?
    Simmte zumindest so der Ansatz? Oder benötige ich Subquerys? Stehe grad total auf dem Schlauch ...
    Code:
     var query = from k in ctx.tblkontrakt
                                    join kEinzel in ctx.tblkontrakteinzelheiten on k.KontraktNummer
                                    equals kEinzel.KontraktNummer
    
                                    join s in ctx.tblstandort on k.KundeID
                                    equals s.StandortID
    
                                    join bEinzel in ctx.tblbestelleinzelheiten on k.KontraktNummer
                                    equals bEinzel.KontraktNummer
    
    
                                    join a in ctx.tblartikel on kEinzel.ident
                                    equals a.ident
    
    
    
                                    join kArt in ctx.tblartikel_kunde_zuordnung on a.ident
                                    equals kArt.ident
    
                                    join b in ctx.tblbestellung on bEinzel.BestellID
                                    equals b.BestellID
    
                                    where kEinzel.ident == bEinzel.ArtikelNummer
                                    where k.KontraktNummer == sKontraktNr
                                    orderby kEinzel.Position
    
                                    
                                    select new Kontrakt
                                    {
                                        KontraktNummer = k.KontraktNummer,
                                        ArtikelNummer = kEinzel.ident,
                                        KundenArtikelNummer = kArt.ArtikelID_Kunde,
                                        ArtikelBezeichnung = a.Bezeichnung_deutsch,
                                        KontraktMenge = (int)kEinzel.Anzahl,
                                        Einzelpreis = (double)kEinzel.Einzelpreis,
                                        Bemerkung = kEinzel.Bemerkung,
                                        Position = (int)kEinzel.Position,
                                        LaufzeitBeginn = (DateTime)k.LaufzeitBeginn,
                                        LaufzeitEnde = (DateTime)k.Laufzeitende,
                                        Bestellmenge = (int)bEinzel.Anzahl,
                                        Kunde = s.Firma_Standort
                                    };
    
                        List<Kontrakt> listKontraktdaten = query.ToList();
    
                        var result = from k in listKontraktdaten
                                     group k by k.ArtikelNummer into g
                                     select new Kontrakt
                                     {
                                         ArtikelNummer = g.Key,
                                         AbgerufeneMenge = g.Sum(k => k.Bestellmenge)
    
                                     };
    
    
    
                        DataTable tbl = IEnumerableToDataTable.ToDataTable(query.ToList());
                        return tbl;
    Zuletzt editiert von OctoberSwimmer; 14.11.2013, 12:56.

  • #2
    Schreib bitte nur das SQL, in anständig formatiert anstatt den StringBuilder Code, mit kurzer Erklärung was der erreichen soll. Ich und vermutlich andere auch haben kaum Lust sich den Sinn erstmal mühevoll zusammenreimen zu müssen.

    Comment


    • #3
      SQL hab ich oben geändert.


      Folgendes Ziel:
      Mit verschiedenen Kunden haben wir Kontrakte. (tblkontrakt).
      Ein Kontrakt enthält mehrere Positionen/Artikel. Die Einzelheiten, welche ArtikelNr, Einzelpreis, Kontraktmenge ist in tblkontrakteinzelheiten. Die Artikeldaten (ArtikelNr, Bezeichnung) in tblartikel.
      Nun soll eine Übersicht zum jeweiligen Kontrakt angezeigt werden.
      Eine Bestellung wird in tblbestelleinzelheiten gespeichert (ArtikelNr, Bestellmenge, Kontraktnummer). Dazu soll dann, je Artikel mit der gewählten Kontraktnummer eine Summe gebildet werden (Abgerufene Menge).



      Ganz simpel hab ich es so versucht, allerdings erhalte ich beim join für query die Fehlermeldung "Der Typ eines Ausdrucks in der join-Klausel ist falsch. Fehler beim Typrückschluss im Aufruf von "GroupJoin"."



      Code:
                          List<Kontrakt> listKontraktdaten = new List<Kontrakt>();
      
                          var qKontrakt = from k in ctx.tblkontrakt
                                          join kEinzel in ctx.tblkontrakteinzelheiten on k.KontraktNummer
                                          equals kEinzel.KontraktNummer
                                          where k.KontraktNummer == sKontraktNr
                                          select new Kontrakt
                                          {
                                              KontraktNummer = k.KontraktNummer,
                                              ArtikelNummer = kEinzel.ident
                                          };
                          listKontraktdaten = qKontrakt.ToList();
      
      
      
                          List<BestellungVK> listBestelldaten = new List<BestellungVK>();
      
                          var qBestellung = from be in ctx.tblbestelleinzelheiten
                                            select new BestellungVK
                                            {
                                                ArtikelNummer = be.ident,
                                                BestellMenge = (int)be.Anzahl,
                                                KontraktNummer = be.KontraktNummer
                                            };
                          listBestelldaten = qBestellung.ToList();
      
      
                          var query = from k in listKontraktdaten
                                      join b in listBestelldaten on k equals b.KontraktNummer into g
                                      from sub in g.DefaultIfEmpty()
                                      select new Kontrakt
                                      {
                                          KontraktNummer = k.KontraktNummer,
                                          AbgerufeneMenge = g.Sum(x => x.BestellMenge),
                                          ArtikelNummer = k.ArtikelNummer
                                      };

      Comment


      • #4
        Du joinst into g? Der Syntax wäre mir unbekannt. Into kenne ich nur beim group und da du Sum benutzt möchtest du scheinbar auch ein group.

        Nochmal zum SQL. Möchtest du auch ein Ergebnis (eben 0) für in tblbestelleinzelheiten nicht vorhandene Artikel?
        Wenn dem nicht so ist lässt sich bei LINQ die Abfrage vermutlich relativ leicht von tblbestelleinzelheiten als Basis ausgehend aufbauen (wäre dann in SQL wohl auch besser oder zumindest für mich lesbarer)

        Comment


        • #5
          Wenn der Artikel nicht im Kontrakt ist, dann muss er gar nicht auftauchen. Falls er doch zum Kontrakt gehört, die Bestellmenge bisher aber 0 ist (also in tblbestelleinzelheiten keinen Eintrag hat), sollte 0 als Bestellmenge angezeigt werden.

          Comment


          • #6
            Ich habe es versucht, anhand dieses Beispieles zu machen: http://msdn.microsoft.com/en-us/libr.../bb397895.aspx
            Den Fehler beim Typrückschluß konnte ich inzwischen lösen.

            Comment


            • #7
              Keiner eine Idee??
              Ich bekomme das echt nicht hin

              Comment


              • #8
                Zu komplex um dir da zu helfen.

                Ich scheitere schon an deinem SQL. tblbestellung scheint völlig überflüssig und tblstandort nur da um an den Standort in die Ergebnismenge zu bekommen.
                Ich würde dir empfehlen das SQL erstmal in eine Form zu bringen die alles überflüssige entfernt und zumindest die beiden genannten Tabellen scheinen völlig überflüssig in Bezug auf das Problem zu sein.
                Wenn es auf das relevante reduziert ist haben wir vielleicht eine Chance das zu durchschauen und dir zu helfen.

                Comment


                • #9
                  Ok, verstehe.

                  Wäre es ansonsten noch eine Möglichkeit, dass ich das ganze als View speichere und diese dann zum Auslesen der Daten verwende?
                  Wobei ich mich mit Views leider überhaupt nicht auskenne ... z.B. müsste ich der Abfrage dann einen Primärschlüssel zuweisen? Falls ja, wie würde dies für mehrere Spalten zum Auslesen aussehen (also eben wie oben).

                  Comment

                  Working...
                  X