How to refactor this code to remove duplicate code

77 views Asked by At

I am writing a c# program where I have the following method. I see that I am writing the same code many a times in this method. I am not able to break the code into reusable pieces. Can somebody take a look at it and suggest ?

private static IOrderedQueryable<T> FormatQuery<T>(IQueryable<T> query, Expression property, ParameterExpression sortParam, SortFilter sortFilter, ref IOrderedQueryable<T> orderedQuery)
{
    if (property.Type == typeof(int))
    {
        var sortExpr = Expression.Lambda<Func<T, int>>(property, new[] { sortParam });
        orderedQuery = !sortFilter.IsDescending 
            ? (orderedQuery == null ? query.OrderBy(sortExpr) : orderedQuery.ThenBy(sortExpr)) 
            : (orderedQuery == null ? query.OrderByDescending(sortExpr) : orderedQuery.ThenByDescending(sortExpr));
    }
    else if (property.Type == typeof(bool))
    {
        var sortExpr = Expression.Lambda<Func<T, bool>>(property, new[] { sortParam });
        orderedQuery = !sortFilter.IsDescending 
            ? (orderedQuery == null ? query.OrderBy(sortExpr) : orderedQuery.ThenBy(sortExpr))
            : (orderedQuery == null ? query.OrderByDescending(sortExpr) : orderedQuery.ThenByDescending(sortExpr));
    }
    else if (property.Type == typeof(DateTimeOffset?))
    {
        var sortExpr = Expression.Lambda<Func<T, DateTimeOffset>>(
        Expression.Coalesce(property, Expression.Constant(DateTimeOffset.MaxValue)), new[] { sortParam });
        orderedQuery = !sortFilter.IsDescending 
            ? (orderedQuery == null ? query.OrderBy(sortExpr) : orderedQuery.ThenBy(sortExpr))
            : (orderedQuery == null ? query.OrderByDescending(sortExpr) : orderedQuery.ThenByDescending(sortExpr));
    }
    else
    {
        var sortExpr = Expression.Lambda<Func<T, object>>(property, new[] { sortParam });
        orderedQuery = !sortFilter.IsDescending 
            ? (orderedQuery == null ? query.OrderBy(sortExpr) : orderedQuery.ThenBy(sortExpr))
            : (orderedQuery == null ? query.OrderByDescending(sortExpr) : orderedQuery.ThenByDescending(sortExpr));
    }
    return orderedQuery;
}

Thanks in advance.

2

There are 2 answers

0
maraaaaaaaa On

Make property a <T2> instead of Expression and put <T, T2> before the params, after the parameters parenthesys you can put where T2 : Expression, now u can just use T2 for properties type, sorry i will write more when i get home i am doing this from cell phone

EDIT: Ok home now so check this out:

private static IOrderedQueryable<T> FormatQuery<T, T2>(IQueryable<T> query, T2 property, ParameterExpression sortParam, SortFilter sortFilter, ref IOrderedQueryable<T> orderedQuery) where T2 : Expression
{
    var sortExpr = Expression.Lambda<Func<T, T2>>(property, new[] { sortParam });
    return !sortFilter.IsDescending 
        ? (orderedQuery == null ? query.OrderBy(sortExpr) : orderedQuery.ThenBy(sortExpr)) 
        : (orderedQuery == null ? query.OrderByDescending(sortExpr) : orderedQuery.ThenByDescending(sortExpr));
}
1
Enigmativity On

Does this help?

    private static IOrderedQueryable<T> FormatQuery<T>(IQueryable<T> query, Expression property, ParameterExpression sortParam, SortFilter sortFilter, ref IOrderedQueryable<T> orderedQuery)
    {
        if (property.Type == typeof(int))
        {
            FormatQueryExtracted(query, GetSortExpr<T, int>(property, sortParam), sortFilter, ref orderedQuery);
        }
        else if (property.Type == typeof(bool))
        {
            FormatQueryExtracted(query, GetSortExpr<T, bool>(property, sortParam), sortFilter, ref orderedQuery);
        }
        else if (property.Type == typeof(DateTimeOffset?))
        {
            FormatQueryExtracted(query, GetSortExpr<T, DateTimeOffset>(Expression.Coalesce(property, Expression.Constant(DateTimeOffset.MaxValue)), sortParam), sortFilter, ref orderedQuery);
        }
        else
        {
            FormatQueryExtracted(query, GetSortExpr<T, object>(property, sortParam), sortFilter, ref orderedQuery);
        }
        return orderedQuery;
    }

    private static Expression<Func<T, P>> GetSortExpr<T, P>(Expression property, ParameterExpression sortParam)
    {
        return Expression.Lambda<Func<T, P>>(property, new[] { sortParam });
    }

    private static void FormatQueryExtracted<T, P>(IQueryable<T> query, Expression<Func<T, P>> sortExpr, SortFilter sortFilter, ref IOrderedQueryable<T> orderedQuery)
    {
        orderedQuery = !sortFilter.IsDescending
            ? (orderedQuery == null ? query.OrderBy(sortExpr) : orderedQuery.ThenBy(sortExpr))
            : (orderedQuery == null ? query.OrderByDescending(sortExpr) : orderedQuery.ThenByDescending(sortExpr));
    }