Hallo zusammen,
ich probiere jetzt seit einiger Zeit bereits diese SQL-Abfrage in C# zu überführen.
Leider hatte ich bisher keinen Erfolg.
So sieht meine SQL-Abfrage aus. Diese funktioniert auch und liefert das gewünscht Ergebnis.
SELECT count(id) as numberOfOrders,
SUM(DATEDIFF(DAY, allocatedDate, orderClosedDate)) as average
FROM orders
WHERE (allocatedDate is not null AND orderClosedDate is not null and orderClosed = 1) AND
(YEAR(allocatedDate) = 2020 AND
YEAR(orderClosedDate) = 2020) AND
(partNumber LIKE '341911%')
Laut meinen Internet-Recherchen muss ich immer in C# Linq, wenn ich einen Count oder SUM machen will, mit GroupBy arbeiten.
Zumindest habe ich noch kein Beispiel ohne GroupBy gefunden.
Das ist mein bisherigere Stand. Allerdings liefert der, wie erwartet wegen dem GroupBY, das falsche Ergebnis.
var result = await this.Db.Order
.GroupBy(g => new { g.Id, g.AllocatedDate, g.OrderClosedDate, g.OrderClosed, g.partNumber})
.Where(w => (w.Key.AllocatedDate != null && w.Key.OrderClosedDate != null && w.Key.OrderClosed == 1) &&
(SqlFunctions.DatePart("yyyy", w.Key.AllocatedDate) == 2020 && SqlFunctions.DatePart("yyyy", w.Key.OrderClosedDate) == 2020) &&
(w.Key.partNumber.StartsWith("341911")))
.Select(s => new
{
NumberOfOrders = s.Count(),
Average = (int)s.Sum(sum => SqlFunctions.DateDiff("day", sum.AllocatedDate.Value, sum.OrderClosedDate.Value))
}).ToListAsync();
Kann da jemand helfen?
Viele Grüße
Das ist korrekt, Du brauchst bei Linq für ein Sum auf die Selektion das GroupBy.
Es sind nicht alle T-SQL Queries 1:1 mit einem ORM darstellbar. Du kannst das aber in eine View auslagern und die View aufrufen.
PS: wenn Du mit EF arbeitest, dann ist die Empfehlung EF.Functions
statt SqlFunctions
zu verwenden.
Was Du aber probieren kannst (weiß nicht, ob es in diesem Fall funktioniert), sind eingebettete Referenzen in Linq.
var query = this.Db.Order
.Where(w => (w.Key.AllocatedDate != null && w.Key.OrderClosedDate != null && w.Key.OrderClosed == 1) &&
(SqlFunctions.DatePart("yyyy", w.Key.AllocatedDate) == 2020 && SqlFunctions.DatePart("yyyy", w.Key.OrderClosedDate) == 2020) &&
(w.Key.partNumber.StartsWith("341911")));
var data = query.Select( _ => new {
NumberOfOrders = query.Count(), // hier dein Count auf Id
Avarage = query.Sum(datedif...) // hier das DateDiff
);
Damit kann man sich viele Queries "hin optimieren", die der Provider sonst oft hinwurstelt. Fast jeder Foren-Query hier basiert auf diesem "Hack".
Hab jetzt hier kein Intellisense, um das zuende zu schreiben. Hoffe die Art und Weise ist jedoch ersichtlich.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Wieder was gelernt.
Mit der View hast du natürlich recht. Wäre wohl mein nächster Schritt gewesen, wenn ich hier keine Antwort bekommen hätte.
Aber dein zweiter Vorschlag "Hack" funktioniert tadellos. Werde wohl erstmal damit weiter machen.
Vielen Dank für die Aufklärung. 🙂