Можно ли клонировать IQueryable в linq? Для целей UNION?
У меня есть стол WorkOrders
, Стол имеет PrimaryWorker
& PrimaryPay
поле. Он также имеет SecondaryWorker
& SecondaryPay
поле (которое может быть null
).
Я хочу выполнить 2 очень похожих запроса и объединить их, чтобы он Worker
Поле & Pay
поле. Так что если один WorkOrder
запись имела как PrimaryWorker
а также SecondaryWorker
поле заполнено, я бы получил 2 записи обратно.
Часть "where" этих двух запросов очень похожа и долго строится. Вот фиктивный пример
var q = ctx.WorkOrder.Where(w => w.WorkDate >= StartDt && w.WorkDate <= EndDt);
if(showApprovedOnly)
{
q = q.Where(w => w.IsApproved);
}
//...more filters applied
Теперь у меня также есть флаг поиска под названием hideZeroPay
, Если это правда, я не хочу включать запись, если работнику заплатили 0 долларов. Но, очевидно, для 1 запроса мне нужно сравнить PrimaryPay
поле, а в другом мне нужно сравнить SecondaryPay
поле.
Поэтому мне интересно, как это сделать.
Могу ли я клонировать свой базовый запрос q
и сделать из него первичный и вторичный рабочий запрос, а затем объединить эти 2 запроса вместе?
2 ответа
Хм, я не уверен, что понимаю ваше намерение. Но я думаю, что клонирование не является необходимым. Почему бы вам не разделить два новых запроса из базового запроса?
var baseQuery = ctx.WorkOrder.Where(w => w.WorkDate >= StartDt && w.WorkDate <= EndDt);
IQueryable<WorkOrder> query1;
if (showApprovedOnly)
{
query1 = baseQuery.Where(w => w.IsApproved);
}
//more filters on query1
...
IQueryable<WorkOrder> query2;
if (/*something*/)
query2 = baseQuery.Where(w => w.SomeThing);
После определения ваших запросов вы можете интерпретировать их (для каждого перечисления) и получать различные результаты.
var res1 = query1.ToList();
var res2 = query2.ToList();
Когда вы делаете свой второй, где вы на самом деле клонировать свой запрос.
Здесь вы создаете свой начальный запрашиваемый объект.
var q = ctx.WorkOrder.Where(w => w.WorkDate >= StartDt && w.WorkDate <= EndDt);
Здесь вы создаете новый запрос с указанием, где
if(showApprovedOnly)
{
q = q.Where(w => w.IsApproved);
}
//...more filters applied
Все, что вам нужно сделать, это создать новую переменную для хранения измененного запроса.
var qw = q.Where(w=> w.IsApproved);
Это работает, потому что запрашиваемый объект создается как объект, а сам запрос выполняется только после его перечисления.