How can I pass an entity property as a parameter of a LINQ Expression?
public DropdownFilter(WhatTypeHere? ABC)
{
// I want to store a selected property here
// ABC must be a property of TEntity
this.ABC = ABC;
}
// I want the class to encapsulate a LINQ query and just parametrize it with a property
public override IQueryable<TEntity> Filter(IQueryable<TEntity> filteredEntityCollection, string value)
{
// ABC is a property of TEntity
return filteredEntityCollection.Where(this.ABC == value);
}
I will be using it like this:
new DropdownFilter<Invoice>(invoice => invoice.SomeProperty);
I have already tried with Expression<Func<TEntity, string>>
kind of parameter, but it didn't work out. It's complaining about
The LINQ expression node type 'Invoke' is not supported in LINQ to Entities.
You have to build LINQ expression manually. First of all I would add second generic parameter to your class, which would specify type of property and type of value which you would pass to filter:
public class DropdownFilter<TEntity, TProperty>
Next you should pass property selector expression to constructor of this filter class:
private PropertyInfo propertyInfo;
public DropdownFilter(Expression<Func<TEntity, TProperty>> propertySelector)
{
this.propertyInfo = (PropertyInfo)((MemberExpression)propertySelector.Body).Member;
}
And last, build lambda expression to filter queryable by given value of specified property:
public IQueryable<TEntity> Filter(
IQueryable<TEntity> filteredEntityCollection, TProperty value)
{
var param = Expression.Parameter(typeof(TEntity), "p");
var lambda = Expression.Lambda<Func<TEntity, bool>>(
Expression.Equal(
Expression.Property(param, propertyInfo),
Expression.Constant(value)
), param);
return filteredEntityCollection.Where(lambda);
}
Usage:
var filter = new DropdownFilter<Invoice, string>(i => i.ABC);
var result = filter(db.Invoices, "foo"); // strongly-typed parameter here
I would add validation of property selector expression passed to the constructor. You should check whether it's a MemberExpression. And you can verfiy property type to support only primitive types of properties.