Условная логика с синтаксисом запроса linq
У меня есть условие ниже, которое выполняет один из двух запросов, которые отличаются только дополнительным предложением
&& acc.Fb_DataSourceKey == dskId
Вот условно
var statData = dskId != -1 ? from s in dao.fb_statdata
join acc in dao.fb_datasourceadaccount
on s.Fb_DataSourceAdAccountId equals acc.Id
where s.ReportTypeId == 1
&& acc.Fb_DataSourceKey == dskId
group new { s, acc.Fb_DataSourceKey } by new { s.Fb_DataSourceAdAccountId, s.Start_time } into res
select res
:
from s in dao.fb_statdata
join acc in dao.fb_datasourceadaccount
on s.Fb_DataSourceAdAccountId equals acc.Id
where s.ReportTypeId == 1
group new { s, acc.Fb_DataSourceKey } by new { s.Fb_DataSourceAdAccountId, s.Start_time } into res
select res;
Теперь, благодаря /questions/29648733/linq-zapros-s-uslovnyim-predlozheniem-where/29648745#29648745 я знаю, что могу изменить его на ниже
var statData = from s in dao.fb_statdata
join acc in dao.fb_datasourceadaccount
on s.Fb_DataSourceAdAccountId equals acc.Id
where s.ReportTypeId == 1
group new { s, acc.Fb_DataSourceKey } by new { s.Fb_DataSourceAdAccountId, s.Start_time } into res
select res;
if (singleDsk)
statData = from s in statData where s.Key.Fb_DataSourceAdAccountId == dskId select s;
Это исключает дублирование кода, но приводит к ужасно неэффективному внешнему объединению (понятно, правда). FTR мы используем MySQL для нашей БД.
Внешнее соединение, к сожалению, неприемлемо медленное. Есть ли способ сделать условный стиль запроса без создания внешнего соединения и без дублирования кода?
1 ответ
Решение
Делайте фильтр до объединения, а не после.
var accounts = dao.fb_datasourceadaccount.AsQueryable();
if(dskId != -1)
accounts = accounts.Where(acc => acc.Fb_DataSourceKey == dskId);
var statData = from s in dao.fb_statdata
join acc in accounts
on s.Fb_DataSourceAdAccountId equals acc.Id
where s.ReportTypeId == 1
group new { s, acc.Fb_DataSourceKey }
by new { s.Fb_DataSourceAdAccountId, s.Start_time }
into res
select res;