una tipos tipo tablas solo puede primitivos este enumeraciĆ³n entidad ejemplos contexto consultas consulta construir complejo admiten linq-to-sql

linq to sql - tipos - C#LINQ equivalente a una consulta SQL algo compleja



solo se admiten tipos primitivos o tipos de enumeraciĆ³n en este contexto (2)

Entonces tengo una consulta SQL como sigue

SELECT P.Date, P.CategoryName, P.ProductName, SUM(Quantity) Quantity, SUM(Sales) TotalSales, IsLevelThree FROM Products P LEFT JOIN LevelThreeTracking LTT ON P.Date = LTT.Date AND P.CategoryName = P.CategoryName AND P.SecurityID = LTT.SecurityID WHERE P.Date = ''12-31-2007'' AND P.CategoryName= ''CategoryName'' GROUP BY P.Date, P.CategoryName, P.ProductName, LTT.IsLevelThree HAVING SUM(Quantity) <> 0 ORDER BY P.ProductName

Estoy tratando de convertirlo a la sintaxis de C # LINQ y tengo la configuración de DataContext con las 2 tablas. Lo intenté un par de veces (última revisión a continuación) pero el sql que se genera parece monstruosamente complejo y se agota. dtpBeginning es un DateTimePicker.

var results = from p in dbFAS.Products group p by new {p.Date, p.CategoryName, p.ProductName} into gp join ltt in dbFAS.LevelThreeTracking on new {gp.Key.Date, gp.Key.CategoryName, gp.Key.ProductName} equals new {ltt.Date, ltt.CategoryName, ltt.ProductName} into everything from e in everything.DefaultIfEmpty() where gp.Key.Date == dtpBeginning.Value.Date && gp.Key.CategoryName == "CategoryName" && gp.Sum(p=>p.Quantity) != 0 select new { gp.Key.Date, gp.Key.CategoryName, gp.Key.ProductName, Quantity = gp.Sum(hp=>hp.Quantity), TotalSales = gp.Sum(hp=>hp.Sales), e.Level3 };

¿Hay algo simple que me estoy perdiendo? ¿Alguna idea sobre cómo refactorizar la declaración LINQ para obtener algo mejor?


¿Realmente se debe convertir a LINQ? Sugeriría que coloques esa consulta en un procedimiento almacenado porque la consulta LINQ equivalente es dolorosamente ilegible y no se puede mantener.


Prueba esta consulta y avísame si funciona. Cambié el join en una cláusula where, esto debería eliminar todas las subconsultas complejas que LINQ genera al traducir a SQL.

No estoy seguro de si obtuve la parte LEFT OUTER JOIN correcta. Acabo de incluir una condición OR que prueba si existe un lado.

from p in dbFAS.Products from ltt in dbFAS.LevelThreeTracking where p.CategoryName == "CategoryName" && (p.Date == ltt.Date || p.Date) && (p.CategoryName == ltt.CategoryName || p.CategoryName) && (p.ProductName == ltt.ProductName || p.ProductName) && p.Quantity > 0 group p by new {p.Date, p.CategoryName, p.ProductName, p.Quantity, p.Sales, ltt.Level3} into gp select new { gp.Key.Date, gp.Key.CategoryName, gp.Key.ProductName, Quantity = gp.Sum(hp=>hp.Quantity), TotalSales = gp.Sum(hp=>hp.Sales), ltt.Level3 };

EDIT: lo pensé un poco más, y esto podría ser un poco más claro e incluso podría compilar! (El último no lo hará debido a las cláusulas ||

from gp in (from p in dbFAS.Products join ltt in dbFAS.LevelThreeTracking on new {p.Date, p.CategoryName, p.ProductName} equals new {ltt.Date, ltt.CategoryName, ltt.ProductName} into temp where p.CategoryName == "CategoryName" && p.Quantity > 0 from t in temp.DefaultIfEmpty() select new { p.Date, p.CategoryName, p.ProductName, p.Quantity, p.Sales, t.Level3 }) group gp by new {gp.Date, gp.CategoryName, gp.ProductName, gp.Level3} select new { gp.Key.Date, gp.Key.CategoryName, gp.Key.ProductName, Quantity = gp.Sum(hp=>hp.Quantity), TotalSales = gp.Sum(hp=>hp.Sales), gp.Level3 }