Using union inside a foreach loop for linq to sql - linq

In the below code I expect to retrn n rows but it always returns zero rows as my initial set has zero records. Ideally it should be doing a UNION ALL and returning me records for all of the integers in the integer list clearanceTotals{6,7,8,9,17}
Any idea how to go about it?
var tbl = (from a in db.Applicants
where a.Id == null
select new { a.Id, a.Firstname, a.Lastname });
int thisTag;
foreach (int c in clearanceTotals)
{
switch (c)
{
case 6:
thisTag = 38;
break;
case 8:
thisTag = 39;
break;
case 17:
thisTag = 39;
break;
case 7:
thisTag = 42;
break;
case 9:
thisTag = 44;
break;
}
tbl = (from a in db.Applicants
join ad in db.ApplicantDeployments on a.Id equals ad.ApplicantId
join aa in db.ApplicantAttachments on a.Id equals aa.ApplicantId
where a.Nationality == 15 && a.DoNotUse == false && a.ClearanceStatus == c
&& aa.Tag == thisTag
select new { a.Id, a.Firstname, a.Lastname }).Union(tbl);
}

I think the problem is that you're capturing the loop variable (c) in the query, so when the query is executed, it uses only the latest value of c. Try copying c to a variable inside the loop:
foreach (int c in clearanceTotals)
{
int c2 = c;
...
...
where a.Nationality == 15 && a.DoNotUse == false && a.ClearanceStatus == c2
...

OK so i got this to work but its additional code plus additional variables
var temp = (from a in db.Applicants
where a.Id == null
select a.Id).ToList();
int thisTag;
foreach (int c in clearanceTotals)
{
switch (c)
{
case 6:
thisTag = 38;
break;
case 8:
thisTag = 39;
break;
case 17:
thisTag = 39;
break;
case 7:
thisTag = 42;
break;
case 9:
thisTag = 44;
break;
}
temp = temp.Union(from a in db.Applicants
join ad in db.ApplicantDeployments on a.Id equals ad.ApplicantId
join aa in db.ApplicantAttachments on a.Id equals aa.ApplicantId
where a.Nationality == 15 && a.DoNotUse == false && a.ClearanceStatus == c
&& aa.Tag == thisTag
select a.Id).ToList();
}
var tbl = (from a in db.Applicants
join ad in db.ApplicantDeployments on a.Id equals ad.ApplicantId
where temp.Contains(a.Id)
select new { a.Id, a.Firstname, a.Lastname }).Distinct();

Related

AVL tree insert case need a clarify

I read several online document about implementing AVL tree using balance factor(Not using a height data field in Node structure), when insert into the tree, there is one case I could not figure out.
The document is from here(also from here has similar function) , the balance factor is defined as height(right-subtree) - height(left-subtree), value in [-1,0,1].
Insert method is implemented as :
public avlitem insertAVL(avlitem root, avlitem newstudent)
{
if(root == null) {
root = newstudent;
unbalance = true;
}
else if(root.idno == newstudent.idno)
System.err.println("No duplicates are allowed");
else if (root.idno > newstudent.idno)
{
root.leftchild=insertAVL(root.leftchild, newstudent);
if (unbalance )
{
switch(root.bfactor)
{ case -1:
root = balancefromleft(root);
unbalance=false;
break;
case 0:
root.bfactor = -1;
unbalance = true;
break;
case 1:
root.bfactor = 0;
unbalance = false;
}
}
}
else
{
root.rightchild=insertAVL(root.rightchild, newstudent);
if (unbalance )
{
switch(root.bfactor)
{
case -1 :
root.bfactor = 0;
unbalance = false;
break;
case 0:
root.bfactor=1;
unbalance = true;
break;
case 1 :
root = balancefromright(root);
unbalance = false;
}
}
}
return root;
}
And insert into the left child ,we use balancefromleft to reblance the tree:
public avlitem balancefromleft(avlitem root)
{
avlitem p;
avlitem w;
p = root.leftchild;
switch(p.bfactor)
{
case -1:
root.bfactor=0;
p.bfactor = 0;
root = rotatetoright(root);
break;
case 0 : System.err.println("can't balance from the left");break;
case 1 : w = p.rightchild;
{
switch (w.bfactor)
{
case -1:root.bfactor = 1;p.bfactor = 0;break;
case 0: root.bfactor = 0; p.bfactor = 0;break; // what is this case ?
case 1: root.bfactor = 0;p.bfactor = -1;
}
w.bfactor = 0;
p = rotatetoleft(p);
root.leftchild = p;
root = rotatetoright(root);
}
}
return root;
}
In the above balancefromleft function, we have a right rotate and double rotate case.
1)The right rotate case is : insert into left child of node y.
T1, T2, T3 and T4 are subtrees.
z y
/ \ / \
y T4 Right Rotate (z) x z
/ \ - - - - - - - - -> / \ / \
x T3 T1 T2 T3 T4
/ \
T1 T2
2) The left then right rotate case: insert into right child of y.
z z w
/ \ / \ / \
y T4 Left Rotate (y) w T4 Right Rotate(z) y z
/ \ - - - - - - - - -> / \ - - - - - - - -> / \ / \
T1 w y T3 T1 T2 T3 T4
/ \ / \
T2 T3 T1 T2
My question:
In the left-then-right rotate case, what case can cause the w.bfactor = 0 ?
In my mind, this could only be possible when remove node of T4 and T4 become shorter than before.How could it be possible when insert node ?
switch (w.bfactor)
{
case -1:root.bfactor = 1;p.bfactor = 0;break;
case 0: root.bfactor = 0; p.bfactor = 0;break; // what is this case ?
case 1: root.bfactor = 0;p.bfactor = -1;
}

Linq FirstOrDefault List inside a query

I have this linq query
var numberGroups =
from n in VISRUBs.Where(a => a.VISANA.VISITE.DATEVIS <= d && a.VISANA.VISITE.PANUM == p)
group n by n.RUBRIQUE into g
select new {
RemainderCHAPLIB = g.Key.ANALYSE.CHAPITRE.LIBELLE,
RemainderLIB = g.Key.LIBELLE,
RemainderRUNUM = g.Key.RUNUM,
vals = from vlist in g.OrderByDescending(a=>a.VISANA.VISITE.DATEVIS)
select vlist.VALEUR
};
which gives me this result in Linqpad
What I want is to select the first and second item from the last field (vals) which is a List<string>.
I have tried this:
var numberGroups =
from n in VISRUBs.Where(a => a.VISANA.VISITE.DATEVIS <= d && a.VISANA.VISITE.PANUM == p)
group n by n.RUBRIQUE into g
select new {
RemainderCHAPLIB = g.Key.ANALYSE.CHAPITRE.LIBELLE,
RemainderLIB = g.Key.LIBELLE,
RemainderRUNUM = g.Key.RUNUM,
vals = from vlist in g.OrderByDescending(a => a.VISANA.VISITE.DATEVIS)
select vlist.VALEUR
};
var lst = from n in numberGroups
select new
{
RemainderCHAPLIB = n.RemainderCHAPLIB,
RemainderLIB = n.RemainderLIB,
RemainderRUNUM = n.RemainderRUNUM,
VAL = n.vals.FirstOrDefault()
};
but it didn't work, I got an exception:
Dynamic SQL ErrorSQL error code = -104Token unknown - line 54, column 1OUTER
found it !
var lst = from n in numberGroups.ToList()
select new
{
RemainderCHAPLIB = n.RemainderCHAPLIB,
RemainderLIB = n.RemainderLIB,
RemainderRUNUM = n.RemainderRUNUM,
VAL = n.vals.FirstOrDefault(),
ANT = n.vals.Skip(1).FirstOrDefault()
};

Apache PIG: apply LIMIT only if parameter is > 0

How can I achieve the following in PIG, within a foreach:
REL = foreach RELS {
if ( cnt == 0 )
limited_result = NULL/Empty;
else
limited_result = LIMIT results cnt ;
generate limited_result.some_field;
}
I cannot use LIMIT, since it validates that the 'cnt' is bigger than 0;
I've tried to use a SPLIT, but apparently it isn't supported within foreach.
How about FILTERing before your FOREACH?
REL = foreach (filter RELS by cnt > 0) {
limited_result = LIMIT results cnt ;
generate limited_result.some_field;
}
If you still need the records where cnt is 0, you could SPLIT first and then generate an empty bag when cnt is 0:
split RELS into ZERO if cnt == 0, NONZERO if cnt > 0;
NZ_LIM = foreach NONZERO {
result = LIMIT results cnt ;
generate limited_result.some_field;
}
Z_LIM = foreach ZERO generate {} as some_field;
REL = union NZ_LIM, Z_LIM;

How break after checking / unchecking a node in a treelist

I have a little problem.
i should implement a logic for a treeList which consist from a single parent and more children grouped into more groups by ID's.
I have an action which treats all nodes:
long callerGroup = -1L;
if (callerNode != null)
{
var service = this.tlServices.GetDataRecordByNode(callerNode) as __ServiceInfo;
if (service != null)
{
callerGroup = service.Group;
}
}
Action<TreeListNodes> action = null;
action = (nodes) =>
{
if (nodes != null && nodes.Count > 0)
{
foreach (TreeListNode node in nodes)
{
if (node.Level == 0 && !node.Checked)
{
node.Checked = true;
break;
}
else
{
var service = this.tlServices.GetDataRecordByNode(node) as __ServiceInfo;
if (service != null)
{
var group = service.Group;
//for ' 1 <= group <= 100' -> Mandatory Service, only ONE from group
if (callerGroup >= 1 && callerGroup <= 100)
{
if (group >= 1 && group <= 100)
{
//node.Checked = true; - not done
}
}
//for ' 101 <= group <= 1000 ' -> Mandatory Service, minimum ONE from group, but allow and MORE
if (callerGroup >= 101 && callerGroup <= 1000)
{
}
//for ' group >= 1001 ' -> optional Service, ALL from group
if (callerGroup >= 1001 && group >= 1001)
{
node.Checked = !node.Checked; // --> DONE.
}
}
}
action(node.Nodes);
}
}
};
action(this.tlServices.Nodes);
I have 3 cases:
#1. if 1 <= group <= 100 -> Mandatory Service, allow only ONE from group
#2. if 101 <= group <= 1000 -> Mandatory Service, allow minimum ONE from group, but allow and MORE
#3. if group >= 1001 -> optional Service, Check/ Uncheck ALL from group.
Result:
The #3 I've done easy, but how can i implement #1.
for #1 i found an implementation:
//for ' 1 <= group <= 100' -> Mandatory Service, only ONE from group
if (callerGroup >= 1 && callerGroup <= 100)
{
if (group >= 1 && group <= 100)
{
foreach (TreeListNode nd in nodes)
{
var svc = this.tlServices.GetDataRecordByNode(nd) as __ServiceInfo;
long gr = svc.Group;
if (gr == callerGroup && nd.Checked == true)
{
nd.Checked = false;
}
}
}
}`

Linq left joining with non trivial condition

This is fine, it produces a left join
var q =
from c in categories
join p in products
on c equals p.Category into ps
from p in ps.DefaultIfEmpty()
select new { Category = c, ProductName = p == null ? "(No products)" : p.ProductName };
But what about if I wanted to do something like this:
...
on p.date between c.startdate and c.enddate
...
var q =
from c in categories
join p in products
on c equals p.Category into ps
from p in ps.DefaultIfEmpty()
where p.date >= c.startdate && p.date <= c.enddate
select new { Category = c, ProductName = p == null ? "(No products)" : p.ProductName };

Resources