Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I clone an IQueryable in linq? For UNION purposes?

I have a table of WorkOrders. The table has a PrimaryWorker & PrimaryPay field. It also has a SecondaryWorker & SecondaryPay field (which can be null).

I wish to run 2 very similar queries & union them so that it will return a Worker Field & Pay field. So if a single WorkOrder record had both the PrimaryWorker and SecondaryWorker field populated I would get 2 records back.

The "where clause" part of these 2 queries is very similar and long to construct. Here's a dummy example

var q = ctx.WorkOrder.Where(w => w.WorkDate >= StartDt && w.WorkDate <= EndDt);

if(showApprovedOnly)
{
   q = q.Where(w => w.IsApproved);
}
//...more filters applied

Now I also have a search flag called hideZeroPay. If that's true I don't want to include the record if the worker was payed $0. But obviously for 1 query I need to compare the PrimaryPay field and in the other I need to compare the SecondaryPay field.

So I'm wondering how to do this.

Can I clone my base query q and make a primary & secondary worker query out of it and then union those 2 queries together?

like image 959
user169867 Avatar asked Jun 14 '10 20:06

user169867


2 Answers

Hmm, I'm not sure that I understand you intention. But I think cloning is not neccessary. Why don't you split two new queries from your base query?


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);

After defining your queries you can interpret them (per enumeration) and retrieve your different results.


var res1 = query1.ToList();
var res2 = query2.ToList();
like image 183
DHN Avatar answered Nov 09 '22 01:11

DHN


When you do your second Where you are actually cloning your query.

Here you create your initial queryable object.

var q = ctx.WorkOrder.Where(w => w.WorkDate >= StartDt && w.WorkDate <= EndDt);

Here you create a new queryable with the where associated

if(showApprovedOnly)
{
   q = q.Where(w => w.IsApproved);
}
//...more filters applied

All you need to do is create a new variable to store the ammended query.

var qw = q.Where(w=> w.IsApproved);

This works because the queryable is created as an object and the query itself is only run once you enumerate it.

like image 37
Jonathan Park Avatar answered Nov 09 '22 02:11

Jonathan Park