Как добавить условие в запрос LINQ, использующий группы? - PullRequest
0 голосов
/ 27 марта 2012

Вот мой текущий, рабочий, запрос:

var lsFooterRow = from i in _context.Inventory
                  where i.ClaimId == claimID
                  && i.Taxable == false
                  group i by new { i.ClaimId }
                      into grp
                      select new
                      {
                          SumOfReplValue = grp.Sum(i => i.Price),
                          SumOfACV = grp.Sum(i => i.ACV),
                          SumOfReplCost = grp.Sum(i => i.ReplacementCost)
                      };

Что бы я хотел добавить, чтобы сделать его условным, это что-то вроде этого, так что он добавляет фильтр к базовому запросу вместе с ClaimID и Taxable:

if (reportType == "R")
            lsFooterRow = lsFooterRow.Where(i => i.ReplCost > 0);

Это не работает, потому что не распознает ReplCost, только SumOfReplValue, SumOfACV и SumOfReplCost.

Может кто-нибудь сказать мне, без выполнения запроса в два шага, способ добавить это условие? Если нет способа сделать это, мы будем признательны за двухэтапный подход: -)

Заранее спасибо!

Ответы [ 3 ]

3 голосов
/ 27 марта 2012

Если я правильно понимаю, вам, вероятно, следует разбить начальный запрос на несколько частей.

  var lsFooterRow = from i in _context.Inventory
              where i.ClaimId == claimID
              && i.Taxable == false
              select i;

  // conditional where
  if (reportType == "R")
        lsFooterRow = lsFooterRow.Where(i => i.ReplacementCost > 0);


  var aggregateFooterRow =  from i in lsFooterRow
         group i by new { i.ClaimId }
                  into grp
                  select new
                  {
                      SumOfReplValue = grp.Sum(i => i.Price),
                      SumOfACV = grp.Sum(i => i.ACV),
                      SumOfReplCost = grp.Sum(i => i.ReplacementCost)
                  };

Таким образом, вы фильтруете стоимость замещения до ее агрегирования, что звучит как то, что вы хотите сделать.

Вы выражали беспокойство по поводу запроса из двух частей, но это не должно вызывать проблем. Приятно то, что он не будет составлять и выполнять sql, пока вы не перечислите окончательную версию запроса. Движок платформы сущностей достаточно умен, чтобы просто добавить второй оператор where в качестве еще одного условия в конечный оператор where в SQL. Это означает, что ваше условное место будет аккуратно частью запроса, а не запоздалой мыслью. Вы можете разбить запрос и добавить условные вещи сколько захотите.

Возможность разбить запрос на несколько частей и условно составить запрос - это огромное преимущество LINQ по сравнению с SQL.

1 голос
/ 27 марта 2012

@ Ответ Девина, вероятно, является самым чистым и делает важный вывод о задержке выполнения linq и о том, что 2 шага не означают два запроса. При этом , если вы хотите сделать это в одном запросе, вы можете написать первый запрос, включив в него дополнительное условие, например:

var lsFooterRow = from i in _context.Inventory
                  where i.ClaimId == claimID
                  && i.Taxable == false
                  && (i.ReplacementCost > 0 || reportType != "R")
                  group i by new { i.ClaimId }
                      into grp
                      select new
                      {
                          SumOfReplValue = grp.Sum(i => i.Price),
                          SumOfACV = grp.Sum(i => i.ACV),
                          SumOfReplCost = grp.Sum(i => i.ReplacementCost)
                      };

РЕДАКТИРОВАТЬ: Хм, единственное, что я могу придумать, это может привести к сбою, и работа @ Devin - это если вы меняете значение reportType между этим объявлением и тем, где когда-либо происходит фактическое перечисление lsFooterRow.Если это происходит, вы всегда можете просто .ToList () немедленно.Или, не так много ресурсов, скопируйте reportType во временную переменную, которая никогда не изменялась, и вместо этого ссылайтесь на нее в своем запросе.

string _reportType = reportType //only set here, nowhere else
var lsFooterRow = from i in _context.Inventory
                  where i.ClaimId == claimID
                  && i.Taxable == false
                  && (i.ReplacementCost > 0 || _reportType != "R")
                  group i by new { i.ClaimId }
                      into grp
                      select new
                      {
                          SumOfReplValue = grp.Sum(i => i.Price),
                          SumOfACV = grp.Sum(i => i.ACV),
                          SumOfReplCost = grp.Sum(i => i.ReplacementCost)
                      };

Но теперь он уже не такой чистый и перехватывает переменную _reportType без необходимости внутризакрытие

0 голосов
/ 27 марта 2012

если вы знаете, какой sql-запрос нужно выполнить в БД ... вы можете попробовать http://www.linqpad.net/, что, на мой взгляд, очень удобно, когда вы работаете с linq ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...