Reputation: 1392
I am new to linq c# , Following is my function
public static IQueryable<T> BuildWhereExpression<T>(this IQueryable<T> query, SearchAttributes searchModel)
{
string FilterField = searchModel.FilterField;
string FilterOperator = searchModel.FilterOperator;
string FilterValue = searchModel.FilterValue;
ParameterExpression ParamExp = Expression.Parameter(typeof(T), GlobalConstants.SearchExpressionName);
Expression InitialExp;
LambdaExpression FinalExp;
switch (FilterOperator)
{
case GlobalConstants.IsEqualTo:
if (FilterValue == "")
InitialExp = Expression.Call(Expression.PropertyOrField(ParamExp, FilterField), typeof(string).GetMethod("Contains"), Expression.Constant(FilterValue));
else
InitialExp = Expression.Equal(Expression.PropertyOrField(ParamExp, FilterField), Expression.Constant(FilterValue));
break;
case GlobalConstants.Contains:
{ // This is what i havd tried till now
//var Column = Expression.PropertyOrField(ParamExp, FilterField);
//var isNull = Expression.Equal(Column, Expression.Constant(null));
//Expression left = Expression.Call(Column, typeof(string).GetMethod("ToString", System.Type.EmptyTypes));
//Expression left = Expression.Call(pe)
}
InitialExp = Expression.Call(Expression.PropertyOrField(ParamExp, FilterField), typeof(string).GetMethod("Contains"), Expression.Constant(FilterValue));
break;
case GlobalConstants.StartsWith:
InitialExp = Expression.Call(Expression.PropertyOrField(ParamExp, FilterField), typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) }), Expression.Constant(FilterValue));
break;
default:
InitialExp = Expression.Constant(true);
break;
}
FinalExp = Expression.Lambda<Func<T, bool>>(InitialExp, new ParameterExpression[] { ParamExp });
MethodCallExpression result = Expression.Call(typeof(Queryable), "Where", new Type[] { query.ElementType }, query.Expression, Expression.Quote(FinalExp));
return query.Provider.CreateQuery<T>(result);
}
The above code adds a condition for contains in a column dynamically. Contains does not works for column containing null values. How can i implement following logic
If table.ColumnValue is Null replace the column null with empty string then compair with the value in FilterValue
EDIT: I mean how can i implement query as coalesce(table.column,string.empty) == FilterValue
Please help me over this. Thanks in advance.
Upvotes: 1
Views: 4319
Reputation: 111850
The expression you are looking for is something like:
Expression<Func<T, bool>> exp = x => (x.FilterField ?? string.Empty).Contains(FilterValue);
that can be obtained with
var coalesce = Expression.Coalesce(
Expression.PropertyOrField(ParamExp, FilterField),
Expression.Constant(string.Empty))
so
InitialExp = Expression.Call(coalesce, typeof(string).GetMethod("Contains"), Expression.Constant(FilterValue));
Note that, considering future-proofing, I would always explicitly tell the .NET the parameters of the method I'm looking for:
typeof(string).GetMethod("Contains", BindingFlags.Instance | BindingFlags.Public, null, new[] { typeof(string) }, null);
because you can't know if, in .NET ∞.0, they'll finally add an overload that supports a StringComparison
:-)
Upvotes: 3