LINQ zu SQL:Komplizierte Abfrage mit aggregierten Daten für einen Bericht aus mehreren Tabellen für ein Bestellsystem

StackOverflow https://stackoverflow.com/questions/512984

Frage

Ich wollen zu konvertieren Sie die folgende Abfrage in LINQ-syntax.Ich bin eine sehr viel Mühe zu verwalten, um es zu bekommen zu arbeiten.Ich versuchte wirklich ab LINQ, aber festgestellt, dass ich vielleicht mehr Glück haben, wenn ich schrieb es die andere Weise herum.

SELECT
    pmt.guid,
    pmt.sku,
    pmt.name,
    opt.color,
    opt.size,
    SUM(opt.qty) AS qtySold,
    SUM(opt.qty * opt.itemprice) AS totalSales,
    COUNT(omt.guid) AS betweenOrders
FROM
    products_mainTable pmt 
        LEFT OUTER JOIN 
            orders_productsTable opt ON opt.products_mainTableGUID = pmt.guid
            LEFT OUTER JOIN orders_mainTable omt ON omt.guid = opt.orders_mainTableGUID AND
                (omt.flags & 1) = 1
GROUP BY
    pmt.sku, opt.color, opt.size, pmt.guid, pmt.name
ORDER BY
    pmt.sku

Die Ende Ergebnis ist eine Tabelle, die mir zeigt Informationen über ein Produkt, wie, die Sie oben sehen können.Wie Schreibe ich diese Abfrage in LINQ-Formular, über das begreifen der syntax ?

Außerdem, ich kann wollen, um weitere Filter hinzuzufügen (um die orders_mainTable, zum Beispiel).

Hier ist ein Beispiel, das ich versucht habe, zu arbeiten, und war ziemlich nahe, aber ich bin nicht sicher, ob es das "richtige" Weg, und war nicht in der Lage, der Gruppe, der es nach Größe und Farbe aus dem orders_productsTable.

from pmt in products_mainTable
let Purchases = 
        from opt in pmt.orders_productsTable
        where ((opt.orders_mainTable.flags & 1) == 1)
        where ((opt.orders_mainTable.date_completedon > Convert.ToDateTime("01/01/2009 00:00:00")))
        select opt
orderby pmt.sku
select new {
    pmt.guid,
    pmt.sku,
    pmt.name,
    pmt.price,  
    AvgPerOrder = Purchases.Average(p => p.qty).GetValueOrDefault(0),
    QtySold = Purchases.Sum(p => p.qty).GetValueOrDefault(),
    SoldFor = Purchases.Sum(p => p.itemprice * p.qty).GetValueOrDefault()           
}

*Edit:

Ein wenig deutlicher, so können Sie verstehen, was ich versuche zu tun ist, hier ist etwas mehr Erklärung.

Produkte gespeichert in products_mainTable Bestellungen werden gespeichert in orders_mainTable Produkte, die Bestellt Wurden, sind gespeichert in orders_productsTable

Ich will erstellen Sie mehrere Berichte, die auf Produkten basieren, Bestellungen, etc.bohren in die Daten und finden sinnvolle bits, um die Anzeige zu die Ende Benutzer.

In diesem Fall, bin ich versucht zu zeigen, welche Produkte gekauft wurden, über einen Zeitraum von Zeit, und die beliebtesten sind.Wie viele verkauft, zu welchem Preis und was ist die breakout pro Bestellung.Vielleicht nicht die beste Ordnung, aber ich bin einfach zu Experimentieren und nahm diese ein.

Alle Tabellen haben die Beziehungen zu anderen Tabellen.So aus der product-Tabelle, die ich bekommen kann, um was bestellt bestellt, das Produkt, etc.

Das größte problem, das ich habe, ist zu verstehen, wie LINQ funktioniert, vor allem mit der Gruppierung, aggregierte Daten, Erweiterungen, Unterabfragen, etc.Es macht schon Spaß, aber es ist langsam frustrierend, weil ich Schwierigkeiten haben detaillierte Erklärungen auf, wie dies zu tun.

War es hilfreich?

Lösung 2

Bruno, ich danke Ihnen so viel für Ihre Unterstützung!Die FirstOrDefault() war die wohl größte Hilfe.Folgenden sind einige von dem, was Sie getan haben, und eine andere Ressource, die ich kam mit der folgenden, die zu funktionieren scheint schön!Diese LINQ-Abfrage unten, gab mir fast eine exakte Replikation der SQL, die ich oben gepostet.

Hier ist die andere Ressource, die ich gefunden doing a LEFT OUTER JOIN in LINQ: Blog Post

Endgültige Antwort:

 from pmt in products_mainTable
    join opt in orders_productsTable on pmt.guid equals opt.products_mainTableGUID into tempProducts
    from orderedProducts in tempProducts.DefaultIfEmpty()
    join omt in orders_mainTable on orderedProducts.orders_mainTableGUID equals omt.guid into tempOrders
    from ordersMain in tempOrders.DefaultIfEmpty()
    group pmt by new { pmt.sku, orderedProducts.color, orderedProducts.size } into g
    orderby g.FirstOrDefault().sku
    select new {
        g.FirstOrDefault().guid,
        g.Key.sku,
        g.Key.size, 
        QTY = g.FirstOrDefault().orders_productsTable.Sum(c => c.qty),
        SUM = g.FirstOrDefault().orders_productsTable.Sum(c => c.itemprice * c.qty),
        AVG = g.FirstOrDefault().orders_productsTable.Average(c => c.itemprice * c.qty),
        Some = g.FirstOrDefault().orders_productsTable.Average(p => p.qty).GetValueOrDefault(0),
    }

Andere Tipps

Ich bin auch ein Anfänger in LINQ.Ich weiß nicht, ob dies die richtige Art und Weise der Gruppierung von mehrere Felder, aber ich denke, Sie haben zu transformieren diese Gruppierung von Feldern in a die-Taste.Also, vorausgesetzt, dass alle Ihre Gruppierung Felder sind strings oder ints Sie können machen eine Schlüssel wie folgt:

        var qry = from pmt in products_mainTable
                  join opt in orders_productsTable on pmt.guid equals opt.products_mainTableGUID
                  join omt in orders_mainTable on opt.orders_mainTableGUID equals omt.guid
                  where (opt.orders_mainTable.flags & 1) == 1
                  group omt by pmt.sku + opt.price + opt.size + pmt.guid + pmt.name into g
                  orderby g.sku
                  select new
                  {
                      g.FirstOrDefault().guid,
                      g.FirstOrDefault().sku,
                      g.FirstOrDefault().name,
                      g.FirstOrDefault().color,
                      g.FirstOrDefault().price,
                      AvgPerOrder = g.Average(p => p.qty).GetValueOrDefault(0),
                      QtySold = g.Sum(p => p.qty).GetValueOrDefault(),
                      SoldFor = g.Sum(p => p.itemprice * p.qty).GetValueOrDefault()
                  };

Ich habe nicht testen Sie dieses, so bitte sehen, ob dies hilft Ihnen in irgendeiner Weise.

Das war sehr hilfreich für mich danke.Ich hatte ein ähnliches Problem, mit dem ich versucht hatte, Sie zu Sortieren die sich nur über meinem Fall war viel einfacher als ich hatte keine joins in es.Ich war einfach nur versuchen, die Gruppe ein Feld, Holen Sie sich die min der anderen, und die Anzahl.(min und count in derselben Abfrage)

Hier ist die SQL, die ich wollte, um neu in Linq-syntax:

select t.Field1, min(t.Field2), COUNT(*)
from SomeTable t
group by t.Field1
order by t.Field1

Dank Ihrem post habe ich es schließlich geschafft, kommen mit diesem:

from t in SomeTable
group t by new { t.Field1 } into g
orderby g.Key.Field1
select new
{ 
  g.Key.Field1,
  code = g.Min(c => c.Field2),
  qty = g.Count()
}

Das schafft die folgende SQL-hinter den kulissen:

SELECT [t1].[Field1], [t1].[value] AS [code], [t1].[value2] AS [qty]
FROM (
    SELECT MIN([t0].[Field2]) AS [value], COUNT(*) AS [value2], [t0].[Field1]
    FROM [SomeTable] AS [t0]
    GROUP BY [t0].[Field1]
    ) AS [t1]
ORDER BY [t1].[Field1]

Perfekt, genau, was ich vorhatte.Der Schlüssel für mich war, Sie zeigte es möglich, dies zu tun im inneren des neuen {}, das ist etwas, was ich noch nie in Betracht gezogen, es zu versuchen.Das ist riesig, ich fühle mich jetzt wie ich sind, haben ein deutlich besseres Verständnis für die Zukunft.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top