Reputation: 1969
I have a scenario where I dynamically create a WHERE clause from a client-side grid's configuration. The client sends some json to the server which I then parse and subsequently convert into an expression so it can be passed into the repository as a where clause.
For the moment I'm struggling with creating expressions for complex property types, like this one:
public partial class Resource
{
public string DisplayName { get; set; }
public virtual ResourceType ResourceType { get; set; }
}
The code below that does the translation to an expression works well for simple types like the Displayname property. The expression will be something like:
x => x.DisplayName == "ValueEnteredByUserInTheUI"
However, when a value is entered in the grid for the ResourceType property, the expression will ultimately be something like:
x => x.ResourceType == "ValueEnteredByUserInTheUI"
I'm missing one step to convert into this:
x => x.ResourceType.Name == "ValueEnteredByuserInTheUI"
Anyone can point me in the right direction here?
public Expression<Func<T, bool>> GetExpression<TEntity>(string field, string operation, object value, string ignoreCase)
{
Expression<Func<T, bool>> whereClause = default(Expression<Func<T, bool>>);
// Define lambda
ParameterExpression param = Expression.Parameter(typeof(T), "x");
MemberExpression member = Expression.Property(param, field);
// Get property type
Type propertyType = member.Type;
// Get converter for type
TypeConverter converter = TypeDescriptor.GetConverter(propertyType);
// Convert property to type
var result = converter.ConvertFrom(value.ToString());
// Convert value to constant value
ConstantExpression constant = Expression.Constant(result);
Expression comparingExpression = default(BinaryExpression);
switch (operation)
{
case "like":
comparingExpression = Expression.Equal(member, Expression.Convert(constant, member.Type));
break;
default:
break;
}
var lambda = Expression.Lambda<Func<T, bool>>(comparingExpression, param);
whereClause = whereClause == default(Expression<Func<T, bool>>) ? lambda : NewPredicateBuilder.And(whereClause, lambda);
return whereClause;
}
Upvotes: 1
Views: 1906
Reputation: 1969
Apparently not a lot of people are keen on expressions. Anyway, I have created a workaround for this issue. I added another parameter in the method indicating the property name of the complex property of the root object.
// Get property of root object
MemberExpression member = Expression.Property(param, field);
// Get property of property
MemberExpression memberField = Expression.PropertyOrField(member, complexProperty);
It's not very scalable nor generic but this will do it for now.
Upvotes: 6