LINQ: применение фильтра в предложении where, но необходимо проверить значение SUM (подзапроса) - объяснено внутри - PullRequest
0 голосов
/ 25 ноября 2010

У меня есть следующий linq и он отлично работает, но мне нужно иметь возможность проверить переменную и в зависимости от значения показать только подмножество записей.Я объясню ..

Вот SQL

var test = from c in db.C
 select new {
  Period = c.M.Period,
  Group = c.Code,
  Code = c.ClientCode,
  Name = c.ClientName,
  Amount = (System.Int32)
   ((from m0 in db.M
     where
      m0.ClientCode == c.ClientCode
       group m0 by new {
        m0.ClientCode
         } into g
          select new {
           Expr1 = (System.Int32)g.Sum(p => p.Amount)
    }).First().Expr1)
 }

Это возвращает 6 записей, количество в каждой записи следующее

100 200 300 400 500 600

Мне нужно динамически получить переменную where и проверить переменную с именем filter (в c #), а если filter = 1, вернуть все записи <300, а если filter = 2, вернуть все записи> = 300, и еслипеременная пуста, не применяйте никакого фильтра и возвращайте все записи.

Теперь, когда я запутался, это то, что Amount не находится в БД, это фактически подзапрос.

Может кто-нибудь одолжитьрука

Ответы [ 3 ]

3 голосов
/ 25 ноября 2010

Я думаю, это поможет, если вы упростите свой запрос для начала.Вы используете анонимные типы без особой причины (если есть только одно свойство, зачем?) И группируете по значению, по которому вы уже отфильтровали.Другими словами, ваш запрос эквивалентен:

var test = from c in db.C
 select new {
  Period = c.M.Period,
  Group = c.Code,
  Code = c.ClientCode,
  Name = c.ClientName,
  Amount = db.M
             .Where(m0 => m0.ClientCode == c.ClientCode)
             .Sum(m0 => m0.Amount)
};

Наличие более простого запроса может облегчить решение остальной части вашей проблемы.Это может быть так просто, как:

var filtered = filter == 1 ? test.Where(t => t.Amount < 300)
             : filter == 2 ? test.Where(t => t.Amount >= 300)
             : test;
1 голос
/ 25 ноября 2010

Я взял ответ Джона и включил фильтр в запрос:

int filter = 1;

Func<int, bool> isRelevant = (amount)=>{
    switch(filter)
    {
        case 1: return amount < 300;
        case 2: return amount > 300;
        default: throw new ArgumentException();
    }
};

var test = from c in db.C
            let amount = db.M
                            .Where(m0 => m0.ClientCode == c.ClientCode)
                            .Sum(m0 => m0.Amount)
            where isRelevant(amount)
            select new
            {
                Period = c.M.Period,
                Group = c.Code,
                Code = c.ClientCode,
                Name = c.ClientName,
                Amount = amount
            };
1 голос
/ 25 ноября 2010

попробуйте

var test = from c in db.C
select new {

    Period = c.M.Period,
    Group = c.Code,
    Code = c.ClientCode,
    Name = c.ClientName,
    Amount = (System.Int32)
        ((from m0 in db.M
            where
            m0.ClientCode == c.ClientCode
            group m0 by new {
            m0.ClientCode
                } into g
                select new {
                Expr1 = (System.Int32)g.Sum(p => p.Amount)
                }).First().Expr1).Where(i => 
                    {
                        if (filter == 1) 
                            i.Expr1 < 300; 
                            else if (filter == 2) 
                            i.Expr1 >= 300; 
                    })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...