Mayank
Mayank

Reputation: 1392

How to replace null with Empty string in Expressions.Expression in c# Linq

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

Answers (1)

xanatos
xanatos

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

Related Questions