【问题标题】:C# LINQ equivalent of a somewhat complex SQL queryC# LINQ 相当于一个有点复杂的 SQL 查询
【发布时间】:2008-12-31 17:13:20
【问题描述】:

所以我有一个如下的 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 看起来非常复杂并且超时。 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 语句以获得更好的东西的任何想法?

【问题讨论】:

    标签: linq-to-sql


    【解决方案1】:

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

    【讨论】:

    • 这是完全可行的(如果没有人提出任何建议,我的下一步就是),但我想知道我的结构是否有缺陷......
    • 你为什么被否决了兄弟!!..有些人太苛刻了
    • JPunyon - 这必须是一个LINQ查询有什么令人信服的理由吗?如果不是,那么请不要为了它自己而使用 LINQ - 在这些情况下,从长远来看它实际上会伤害你(在可读性和可维护性方面)
    • 没有什么特别的原因。为整体设计情绪投票(“正确工作的正确工具”)。但问题的关键在于了解 LINQ 的边界在哪里以及重构如何提供更好的结果。 (当然我可以写SQL,我把它放在问题中)
    • LINQ 与 SQL 代码一样易于维护,前提是您对 LINQ 的了解与对 SQL 的了解一样多。尽管如此,使用 LINQ 还是有很多好处的,stackoverflow.com/questions/14530/…
    【解决方案2】:

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

    我不确定我的 LEFT OUTER JOIN 部分是否正确。我只是包含了一个 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
    }
    

    【讨论】:

      猜你喜欢
      • 2010-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-28
      • 1970-01-01
      • 2018-02-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多