You can write your own extension method In
, here's the IEnumerable:
public static class ExtLinq
{
public static IEnumerable<TSource> In<TSource, TMember>(this IEnumerable<TSource> source,
Func<TSource, TMember> identifier, params TMember[] values) =>
source.Where(m => values.Contains(identifier(m)));
}
use it like this:
context.Records.In(x => x.ID, 1, 2, 3)
if you want the IN
to be executed on server to save data travels, use this IQueryable version, implemented with expressions API:
public static IQueryable<TSource> In<TSource, TMember>(this IQueryable<TSource> source,
Expression<Func<TSource, TMember>> identifier, params TMember[] values)
{
var parameter = Expression.Parameter(typeof(TSource), "m");
var inExpression = GetExpression(parameter, identifier, values);
var theExpression = Expression.Lambda<Func<TSource, bool>>(inExpression, parameter);
return source.Where(theExpression);
}
static Expression GetExpression<TSource, TMember>(ParameterExpression parameter, Expression<Func<TSource, TMember>> identifier, IEnumerable<TMember> values)
{
var memberName = (identifier.Body as MemberExpression).Member.Name;
var member = Expression.Property(parameter, memberName);
var valuesConstant = Expression.Constant(values.ToList());
MethodInfo method = typeof(List<TMember>).GetMethod("Contains");
Expression call = Expression.Call(valuesConstant, method, member);
return call;
}
this query (or similar depening on your table) will be executed on server and return desired data:
SELECT
[Extent1].[ID] AS [ID],
[Extent1].[Name] AS [Name]
FROM [dbo].[Records] AS [Extent1]
WHERE [Extent1].[ID] IN (1, 2, 3)