Does anybody know how to apply a \"where in values\" type condition using LINQ-to-Entities? I\'ve tried the following but it doesn\'t work:
var values = new
For the cases when you want to use expressions when querying your data, you can use the following extension method (adapted after http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/thread/095745fe-dcf0-4142-b684-b7e4a1ab59f0/):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Data.Objects;
namespace Sample {
public static class Extensions {
public static IQueryable ExtWhereIn(this ObjectQuery query,
Expression> valueSelector,
IEnumerable values) {
return query.Where(BuildContainsExpression(valueSelector, values));
}
public static IQueryable ExtWhereIn(this IQueryable query,
Expression> valueSelector,
IEnumerable values) {
return query.Where(BuildContainsExpression(valueSelector, values));
}
private static Expression> BuildContainsExpression(
Expression> valueSelector, IEnumerable values) {
if (null == valueSelector) { throw new ArgumentNullException("valueSelector"); }
if (null == values) { throw new ArgumentNullException("values"); }
ParameterExpression p = valueSelector.Parameters.Single();
// p => valueSelector(p) == values[0] || valueSelector(p) == ...
if (!values.Any()) {
return e => false;
}
var equals = values.Select(value => (Expression)Expression.Equal(valueSelector.Body, Expression.Constant(value, typeof(TValue))));
var body = equals.Aggregate((accumulate, equal) => Expression.Or(accumulate, equal));
return Expression.Lambda>(body, p);
}
}
class Program {
static void Main(string[] args) {
List fullList = new List();
for (int i = 0; i < 20; i++) {
fullList.Add(i);
}
List filter = new List();
filter.Add(2);
filter.Add(5);
filter.Add(10);
List results = fullList.AsQueryable().ExtWhereIn(item => item, filter).ToList();
foreach (int result in results) {
Console.WriteLine(result);
}
}
}
}
Using the extensions is really easy (as you can see in the sample). To use it on a database object, assuming you are filtering a table called "Product" by more than one id, you could do something like that:
class Product {
public int Id { get; set; }
/// ... other properties
}
List GetProducts(List productIds) {
using (MyEntities context = new MyEntities()) {
return context.Products.ExtWhereIn(product => product.Id, productIds).ToList();
}
}