Tuesday, April 12, 2011

Reference By Value for integer doesn’t work in entity framework / LINQ query

 

Just find an interesting bugs, where I thought reference by value (int) can be used in entity framework or linq query.

Here is the code



lst = new List<IQueryable<tblProduct>>();
int choiceID = 30;
lst.Add(from t in originalQuery
where t.tblProductChoiceTag.Any(c => c.ChoiceID == choiceID)
select t);
choiceID = 31;
lst.Add(from t in originalQuery
where t.tblProductChoiceTag.Any(c => c.ChoiceID == choiceID)
select t);


IQueryable<tblProduct> q = null;

bool first = true;
foreach (var tquery in lst)
{
if (first)
{
q = tquery;
first = false;
}
else
{ //the next one combine it
q = q.Union(tquery);
}

}











When it executed, linq query will use the last choiceID (31) and override (30).

This really weird, because I thought It is saved to use the same (int) variable because it will pass by value.




Here is another example


var q = (from t in DBHelper.Instance.tblProductVariation
where t.ProductID == pid
&& t.tblChoice.Count == choices.Count
select t);

foreach (var c in choices)
{
q = (from t in q
where t.tblChoice.Any(ch=>ch.ChoiceID == c.ChoiceID)
select t);
}
a
return q.FirstOrDefault();




See on this query which the value will be iterating from the choice object



q = (from t in q
where t.tblChoice.Any(ch=>ch.ChoiceID == c.ChoiceID)
select t);




this code will pass the same value of choiceID.


To fix this you need to change it into local variable.


var cid = c.ChoiceID;

q = (from t in q
where t.tblChoice.Any(ch=>ch.ChoiceID == cid)
select t);







Anyone can explain this ?

No comments: