C # LINQ эквивалент несколько сложного запроса SQL - PullRequest
1 голос
/ 31 декабря 2008

Итак, у меня есть 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 с помощью двух таблиц. Я пытался пару раз (последняя редакция ниже), но генерируемый 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, чтобы получить что-то лучше?

Ответы [ 2 ]

10 голосов
/ 31 декабря 2008

Действительно ли его нужно преобразовать в LINQ? Я бы посоветовал вам поместить этот запрос в хранимую процедуру, потому что эквивалентный запрос LINQ мучительно нечитаем и не поддерживается.

9 голосов
/ 31 декабря 2008

Попробуйте этот запрос и дайте мне знать, если он работает. Я изменил объединение на условие where, это должно устранить все сложные подзапросы, которые LINQ генерирует при переводе на SQL.

Я не уверен, правильно ли я понял часть LEFT OUTER JOIN. Я просто включил условие ИЛИ, которое проверяет, существует ли одна сторона.

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: Я подумал об этом еще немного, и это может быть немного яснее, и это может даже скомпилироваться! (Последнее не из-за предложений ||)

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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...