2017-01-12 6 views
0

У меня есть SQL-запрос следующего типа, и я пытался извлечь данные в моем приложении C# с помощью LINQГруппа по агрегатных функций в LINQ

select 
sum(CASE when outcome = 0 then samplingweight else 0 end) tpcount, 
sum(CASE when outcome = 1 then samplingweight else 0 end) fpcount, 
sum(CASE when outcome = 2 then samplingweight else 0 end) mismatch, 
sum(CASE when outcome = 3 then samplingweight else 0 end) fncount, 
sum(CASE when outcome = 4 then samplingweight else 0 end) tncount, 
sum(samplingweight) totalweight, 
__date, 
scenario from MyTable 
where __date = '30-Dec-16 12:00:00 AM' and scenario = 'parcels' 
group by __date, scenario 

Примечание: samplingweight является двойным значением в БД.

Я пытался и смог добраться до ниже состояния

from pr in this.context.ComputedPrSet 
where 
    pr.Date.Equals(date) && pr.Scenario.Equals(scenario) 
group pr by new { pr.Date, pr.Scenario } 
into grp 
select new 
      { 
       grp.Key.Date, 
       grp.Key.Scenario, 
       TruePositiveCount = grp.Sum(x => x.SamplingWeight) //I am stuck here. Not sure how to aggregate the properties 
      }; 

ПРИМЕЧАНИЕ: date и scenario в приведенном выше запросе LINQ принимаются в качестве параметров функции, выполняющейся.

Любые идеи или советы о том, как действовать?

+0

'grp.Where (x => x.outcome == 1) .Sum (x => x.SamplingWeight) ' – Magnus

ответ

2

У вас есть два легко видимые опции:

  • Фильтр GRP с пунктом .Where() перед тем суммированием
  • Test x.outcome для предпочтительного значения в .Sum()

Я считаю, что первое более читаемое, а последнее более точно соответствует вашему SQL. Они могут переводить на SQL по-разному, в зависимости от вашего провайдера. Если производительность является проблемой, обязательно оцените полученный SQL.

from pr in this.context.ComputedPrSet 
where 
    pr.Date.Equals(date) && pr.Scenario.Equals(scenario) 
group pr by new { pr.Date, pr.Scenario } 
into grp 
select new 
      { 
       grp.Key.Date, 
       grp.Key.Scenario, 
       TruePositiveCount = grp.Where(x => x.outcome == 0).Sum(x => x.SamplingWeight), 
       FPCount = grp.Sum(x => x.outcome == 1 ? x.SamplingWeight : 0), 
      }; 

Третий вариант заключается в группе по дате, сценарий, и исход в БД, а затем повторно Select() в объект, который вы хотите в коде, например, так:

this.Context.ComputedPrSet 
    .Where(pr => pr.Date == date && pr.Scenario == scenario) 
    .GroupBy(pr => new { pr.Date, pr.Scenario, pr.Outcome }) 
    .Select(grp => new { 
     grp.Key.Date, 
     grp.Key.Scenario, 
     grp.Key.Outcome, 
     Count = grp.Sum(pr => pr.SamplingWeight) 
    }) 
    .AsEnumerable() 
    // .AsEnumerable() will "close" the query in LINQ. 
    // Further operations are done via LINQ to Objects after fetching the prior results from your DB 
    .GroupBy(e => new { e.Date, e.Scenario }) 
    .Select(g => new { 
     g.Key.Date, 
     g.Key.Scenario, 
     TruePositiveCount = g.FirstOrDefault(e => e.Outcome == 0), 
     FPCount = g.FirstOrDefault(e => e.Outcome == 1), 
    }); 
0

Оператор ?:CASE WHEN часть.

from pr in this.context.ComputedPrSet 
where 
    pr.Date.Equals(date) && pr.Scenario.Equals(scenario) 
group pr by new { pr.Date, pr.Scenario } 
into grp 
select new 
{ 
    grp.Key.Date, 
    grp.Key.Scenario, 
    TruePositiveCount = grp.Sum(x => x.Outcome == 0?x.SamplingWeight:0) 
}; 

 Смежные вопросы

  • Нет связанных вопросов^_^