views:

127

answers:

1

NOTE: all the code is written Top of my head. It can contains some mistakes. Just get the overall point of this question)

Taking this class definition: (reduced for simplicity)

public class CodedValue
{
  public string Code { get; set; }
  public string Value {get; set; }
}

Taking thoses objects:

CodedValue cv1 = new CodedValue(){ Code = "A",  Value = "1" };
CodedValue cv2 = new CodedValue(){ Code = "B",  Value = "2" };
IList<CodedValue> cvList = new List<CodedValue>();
cvList.Add(cv1);
cvList.Add(cv2);

cvList contains a list of CodedValue to filter.

Lets pretend that my database contains thoses records:

CODE     VALUE
A        1
A        2
B        1
B        2

Now, I want to retrieve all objects where the codedvalue is in the list

var filter = from o in MyRepository.List()
             where cvList.Contains(o.CodedValue)
             select o;

NHibernate translate this Linq to this:

select [Fields...] from [Table...]
where Code in ('A', 'B') and Value in ('1', '2');

This is wrong. If you take a look at my records example, this SQL will returns all the rows. The SQL should be translated to:

select [Fields...] from [Table...]
where (Code = 'A' and Value = '1') or (Code = 'B' and Value = '2');

So, can I get the result I want using Linq? If so, how? If not, how can I achieve that?

Thanks

A: 

Ok, here's the solution!

I'm using PredicateBuilder from this website: PredicateBuilder

Then, I build the predicate:

var expr = PredicateBuilder.False<Audit>();

foreach(CodedValue codedValue in auditEventIds)
{
  CodedValue cv = codedValue;
  expr = expr.Or(a => (a.EventId.Code == cv.Code) && (a.EventId.CodeSystemName == cv.CodeSystemName));
}

itemQuery = itemQuery.Where(expr);

The line CodedValue cv = codedValue in the foreach statement IS VERY IMPORTANT. Omitting the line will construct the correct SQL syntax, but the values of the parameters will be the same for all.

I really hope it will help someone.

vIceBerg