2008-12-31 91 views
1

,所以我有一个SQL查询,如下所示C#LINQ相当于一个有点复杂的SQL查询

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 

我试图将其转换为C#LINQ语法和具有DataContext的设置与2个表。我已经尝试了几次(下面的最新版本),但生成的SQL看起来非常复杂并超时。 dtpBeginning是一个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 
}; 

有没有简单的我失踪了?任何关于如何重构LINQ语句以获得更好的东西的想法?

回答

10

它确实需要转换为LINQ吗?我建议你把这个查询放在存储过程中,因为等价的LINQ查询是痛苦的不可读和不可维护的。

+0

这(如果没有人又发表了什么,我的下一个步骤)是完全可行的,但我在想,如果我的建设是有缺陷的... – 2008-12-31 17:18:27

9

试试这个查询,让我知道它是否有效。我将连接更改为where子句,这应该消除LINQ在转换为SQL时生成的所有复杂子查询。

我不知道我是否得到了左外部连接部分的权利。我只是包含一个OR条件来测试是否存在一个边。

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 
}; 

编辑: 我想过这个问题更多一些,这可能是一个更加清楚一点,它甚至可以编译! (最后一个将因为||条款不)

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 
}