代码之家  ›  专栏  ›  技术社区  ›  Indeed is Trash

C#LINQ相当于一个稍微复杂的SQL查询

  •  1
  • Indeed is Trash  · 技术社区  · 17 年前

    所以我有一个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语法,并使用2个表设置DataContext。我已经尝试过几次了(下面是最新版本),但生成的sql看起来非常复杂,而且超时了。dtpBegining是一个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语句以获得更好的结果有什么想法吗?

    2 回复  |  直到 17 年前
        1
  •  10
  •   Andrew Hare    17 年前

    它真的需要转换为LINQ吗?我建议您将该查询放入存储过程中,因为等效的LINQ查询非常难以读取和维护。

        2
  •  9
  •   Noah    17 年前

    试试这个查询,让我知道它是否有效。我将连接更改为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
    }