Here is my generic method for creating linq expression based on field name of a type, operator (as enumerations of operators generated from XSD) and value of field
private Expression<Func<T, bool>> GetCriteriaPredicate<T>(string fieldName, OperatorRef selectedOperator, string value)
{
PropertyDescriptor prop = TypeDescriptor.GetProperties(typeof(GoodsWorksService)).Find(fieldName, true);
if (prop != null)
{
//value as object
object fieldValue = null;
//GUID
if (prop.PropertyType == typeof(Guid?))
{
fieldValue = new Guid(value) as Guid?;
}
//Integer
if (prop.PropertyType == typeof(int?) || prop.PropertyType == typeof(int))
{
int intValue;
if (Int32.TryParse(value, out intValue))
{
fieldValue = intValue;
}
}
//DateTime
if (prop.PropertyType == typeof(DateTime?) || prop.PropertyType == typeof(DateTime))
{
DateTime dateTimeValue;
if (DateTime.TryParse(value, out dateTimeValue))
{
fieldValue = dateTimeValue;
}
}
//String
if (prop.PropertyType == typeof(string))
{
fieldValue = value;
}
var parameter = Expression.Parameter(typeof(T));
switch (selectedOperator)
{
// "="
case OperatorRef.Item:
{
var body = Expression.Equal(Expression.Property(parameter, prop.Name), Expression.Constant(fieldValue, prop.PropertyType));
return Expression.Lambda<Func<T, bool>>(body, parameter);
}
// "!="
case OperatorRef.Item1:
// "<>"
case OperatorRef.Item2:
{
var body = Expression.NotEqual(Expression.Property(parameter, prop.Name), Expression.Constant(fieldValue, prop.PropertyType));
return Expression.Lambda<Func<T, bool>>(body, parameter);
}
// "<"
case OperatorRef.Item3:
{
var body = Expression.LessThan(Expression.Property(parameter, prop.Name), Expression.Constant(fieldValue, prop.PropertyType));
return Expression.Lambda<Func<T, bool>>(body, parameter);
}
// "<="
case OperatorRef.Item4:
{
var body = Expression.LessThanOrEqual(Expression.Property(parameter, prop.Name), Expression.Constant(fieldValue, prop.PropertyType));
return Expression.Lambda<Func<T, bool>>(body, parameter);
}
// ">"
case OperatorRef.Item5:
{
var body = Expression.GreaterThan(Expression.Property(parameter, prop.Name), Expression.Constant(fieldValue, prop.PropertyType));
return Expression.Lambda<Func<T, bool>>(body, parameter);
}
// ">="
case OperatorRef.Item6:
{
var body = Expression.GreaterThanOrEqual(Expression.Property(parameter, prop.Name), Expression.Constant(fieldValue));
return Expression.Lambda<Func<T, bool>>(body, parameter);
}
//By containing string in field
case OperatorRef.LIKE:
{
MethodInfo contains = typeof(string).GetMethod("Contains");
var body = Expression.Call(Expression.Property(parameter, prop.Name), contains, Expression.Constant(fieldValue, prop.PropertyType));
return Expression.Lambda<Func<T, bool>>(body, parameter);
}
// по умолчанию - "="
default:
{
var body = Expression.Equal(Expression.Property(parameter, prop.Name), Expression.Constant(fieldValue, prop.PropertyType));
return Expression.Lambda<Func<T, bool>>(body, parameter);
}
}
}
return null;
}