I am trying build a dictionary of Expressions that have different input parameter types. I am trying to store the type of the parameter because later down the road I plan to use Reflection to discover a method on the type. Here is the code that creates the dictionary and a generic Add function I created to add entries to it:
public class LoadEntityQuery : IQuery<LoadEntityQueryResult>
{
public IDictionary<Type, Expression<Func<Type, bool>>> Entities { get; set; }
public LoadEntityQuery()
{
Entities = new Dictionary<Type, Expression<Func<Type, bool>>>();
}
public void Add<T>(Expression<Func<T, bool>> where = null) where T : Entity
{
Expression<Func<Type, bool>> _lambda = null;
if (where != null)
{
ParameterExpression param = Expression.Parameter(typeof(T), where.Parameters[0].Name);
var body = Expression.Invoke(where, param);
_lambda = Expression.Lambda<Func<Type, bool>>(body, param);
}
Entities.Add(typeof(T), _lambda);
}
}
The body of the new method is created properly. The issue is when I try to create the new Lambda expression with the type from the expression being passed in, I receive this error:
ParameterExpression of type ‘TestNamespace.TestClass’ cannot be used for delegate parameter of type ‘System.Type’
Does anybody have an idea as to what I can do in this situation? Like I said before, at some point later I am going to loop through this dictionary to do some reflective programming on each entry. If there is a better way to do this I am all ears.
As an example of what I am trying to do, I store the expressions for Where clauses for POCO objects that need to be initialized:
LoadEntityQuery _query = new LoadEntityQuery();
_query.Add<PayrollLocation>();
_query.Add<PayrollGroupBU>();
_query.Add<PersonnelPosition>(t => t.DataSet == MasterDataSet);
_query.Add<EmployeeStatus>();
_query.Add<PayrollGrade>();
This list of Entities will be different for each app. The idea is to collect all the entities and Where clause for each and discover a certain method using reflection on each one. (e.g. PayrollLocation has a GetPayrollLocationsQuery() method, PayrollGroupBU has a GetPayrollGroupBUQuery() method…). The Add method is generic in order for me to make use of the lambda expression in the calling code.
Thanks,
Jason
Looking closely at your code, the expression you generate has some problems. See my explanation at the top of this answer to explain one of them, it’s the same issue here. You’re creating a new lambda where the parameter instance you create here is not used in the body.
The bigger problem is that your expressions are just wrong for what you appear to be trying to do. As far as I can tell, you are just trying to create a mapping from entity types to functions that take an entity of that type and returns a bool.
Type -> Expression<Func<TEntity, bool>>. The expression you build just does not work.You should make the dictionary store non-generic lambdas that way you can store these functions easily without performing conversions or rebuilding the expressions. You will not be able to store them as generic lambdas here. Then cast to the generic lambda when you access them. I’d put this in a separate class to manage the casting and refactor your code to this: