I have a repository class which has a GetAsQueryable
method defined as follows:
public class Repository<TEntity> : IDisposable, IRepository<TEntity> where TEntity : class
{
internal DbSet<TEntity> _DbSet;
public virtual IQueryable<TEntity> GetAsQueryable(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "")
{
IQueryable<TEntity> query = _DbSet;
if (filter != null)
{
query = query.Where(filter);
}
foreach (var includeProperty in includeProperties.Split
(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProperty);
}
if (orderBy != null)
{
return orderBy(query);
}
else
{
return query;
}
}
}
In my calling code I typically do operations such as:
IRepository<Tracking> repoTracking = new Repository<Tracking>(context);
IQueryable<Tracking> tracking = repoTracking.GetAsQueryable();
var results = tracking.Where(t => t.Status_Code_Id == 15).ToList();
This works great; however now I want to be able to build the lambda sent into the .Where
at runtime. I have tried building an expression tree as follows:
IRepository<Tracking> repoTracking = new Repository<Tracking>(context);
IQueryable<Tracking> tracking = repoTracking.GetAsQueryable();
var results = tracking.Where(t => t.Status_Code_Id == 15).ToList();
IRepository<Tracking> repoTracking = new Repository<Tracking>(context);
IQueryable<Tracking> tracking = repoTracking.GetAsQueryable();
ParameterExpression pe = Expression.Parameter(typeof (int), "Status_Code_Id");
LambdaExpression lambda = Expression.Lambda(Expression.Equal(pe, Expression.Constant(15)));
MethodCallExpression whereExpression = Expression.Call(
typeof(Queryable),
"Where",
new Type[] { tracking.ElementType },
tracking.Expression,
lambda);
However, this yields the following exception:
No generic method 'Where' on type 'System.Linq.Queryable' is compatible with the supplied type arguments and arguments. No type arguments should be provided if the method is non-generic.
Why can it not find the Where
method on my instance of Tracking
?
If you want to build t => t.Status_Code_Id == 15
dynamically you need don't need to call Where
using Expression
. Just create Expression<Func<TEntity, bool>>
and pass it to Where
:
ParameterExpression t = Expression.Parameter(typeof(Tracking), "t");
Expression statusCode = Expression.Property(t, "Status_Code_Id");
Expression comparison = Expression.Equal(statusCode, Expression.Constant(15));
Expression<Func<Tracking, bool>> lambda
= Expression.Lambda<Func<Tracking, bool>>(comparison, t);
var results = tracking.Where(lambda).ToList();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With