0

I have method below FilterQuery which sorts the data based on sortPropertyName property.

 private IQueryable<TEntity> FilterQuery(Expression<Func<TEntity, bool>> predicate, string sortPropertyName, OrderBy orderBy = OrderBy.Ascending)
    {
        IQueryable<TEntity> entities = _dbEntitySet;
        entities = (predicate != null) ? entities.Where(predicate) : entities;
        if (string.IsNullOrEmpty(sortPropertyName))
        {
            sortPropertyName = "Id";
        }
        var keySelector = CreateSelectorExpression<TEntity>(sortPropertyName);
        entities = (orderBy == OrderBy.Ascending) ? entities.OrderBy(keySelector) : entities.OrderByDescending(keySelector);
        return entities;
    }

Aforementioned method in turn calls method CreateSelectorExpression .

 private static Expression<Func<TEntity, string>> CreateSelectorExpression<TEntity>(string propertyName)
    {
        try
        {
            var paramterExpression = Expression.Parameter(typeof(TEntity));
            return (Expression<Func<TEntity, string>>)Expression.Lambda(Expression.PropertyOrField(paramterExpression, propertyName),
                                                                    paramterExpression);
        }
        catch (Exception ex)
        {
            string msg = ex.ToString();
            return null;
        }
    }

The above solution works fine when the property is of type string but throw exception in case if property type is numeric or date time. For the time being as you can see I have hard-coded the Id property to raise the exception. Here is the exception which CreateSelectorExpression throws when returning expression:

Unable to cast object of type 'System.Linq.Expressions.Expression1[System.Func2[MyProject.Business.Domain.MyClass,System.Int32]]' to type 'System.Linq.Expressions.Expression1[System.Func2[MyProject.Business.Domain.MyClass,System.String]]

Can you please help me what is going on wrong in my code or another better soltion? Also please let me know if you required some more information from me.

1

1 Answer 1

1

Instead of building your and expression from scratch, you can take an expression over TEntity as key selector in place of the sortPropertyName parameter :

private IQueryable<TEntity> FilterQuery<TValue>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, TValue>> sortExpression, OrderBy orderBy = OrderBy.Ascending)    
{
    IQueryable<TEntity> entities = _dbEntitySet;         
    entities = (predicate != null) ? entities.Where(predicate) : entities;
    entities = (orderBy == OrderBy.Ascending) ? entities.OrderBy(sortExpression) : entities.OrderByDescending(sortExpression);
    return entities;
}

You can remove the CreateSelectorExpression function.

Example of use :

FilterQuery<Test>(p => p.Id > 50, p => p.Id, OrderBy.Ascending)

Will filter the result by item having the Id greater than 50 and sort them by the Id property.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.