0

次のコードがあり、これをリファクタリングして重複コードを削除しようとしています。しかし、リファクタリングしようとするたびに行き詰まります。この問題で私を助けることができる誰かがいますか?

    public static IOrderedQueryable<T> ObjectSort<T>(this IQueryable<T> entities, Expression<Func<T, object>> expression, string order = "asc")
    {
        var sortOrder = order == "asc" ? SortOrder.Ascending : SortOrder.Descending;
        return entities.ObjectSort(expression, sortOrder);
    }

    public static IOrderedQueryable<T> ObjectThenBy<T>(this IOrderedQueryable<T> entities, Expression<Func<T, object>> expression, string order = "asc")
    {
        var sortOrder = order == "asc" ? SortOrder.Ascending : SortOrder.Descending;
        return entities.ObjectThenBy(expression, sortOrder);
    }

    public static IOrderedQueryable<T> ObjectSort<T>(this IQueryable<T> entities, Expression<Func<T, object>> expression, SortOrder order = SortOrder.Ascending)
    {
        var unaryExpression = expression.Body as UnaryExpression;
        if (unaryExpression != null)
        {
            var propertyExpression = (MemberExpression)unaryExpression.Operand;
            var parameters = expression.Parameters;

            if (propertyExpression.Type == typeof(DateTime))
            {
                var newExpression = Expression.Lambda<Func<T, DateTime>>(propertyExpression, parameters);
                return order == SortOrder.Ascending ? entities.OrderBy(newExpression) : entities.OrderByDescending(newExpression);
            }

            if (propertyExpression.Type == typeof(DateTime?))
            {
                var newExpression = Expression.Lambda<Func<T, DateTime?>>(propertyExpression, parameters);
                return order == SortOrder.Ascending ? entities.OrderBy(newExpression) : entities.OrderByDescending(newExpression);
            }

            if (propertyExpression.Type == typeof(int))
            {
                var newExpression = Expression.Lambda<Func<T, int>>(propertyExpression, parameters);
                return order == SortOrder.Ascending ? entities.OrderBy(newExpression) : entities.OrderByDescending(newExpression);
            }

            if (propertyExpression.Type == typeof(int?))
            {
                var newExpression = Expression.Lambda<Func<T, int?>>(propertyExpression, parameters);
                return order == SortOrder.Ascending ? entities.OrderBy(newExpression) : entities.OrderByDescending(newExpression);
            }

            if (propertyExpression.Type == typeof(bool))
            {
                var newExpression = Expression.Lambda<Func<T, bool>>(propertyExpression, parameters);
                return order == SortOrder.Ascending ? entities.OrderBy(newExpression) : entities.OrderByDescending(newExpression);
            }

            throw new NotSupportedException("Object type resolution not implemented for this type");
        }
        return order == SortOrder.Ascending ? entities.OrderBy(expression) : entities.OrderByDescending(expression);
    }

    public static IOrderedQueryable<T> ObjectThenBy<T>(this IOrderedQueryable<T> entities, Expression<Func<T, object>> expression, SortOrder order = SortOrder.Ascending)
    {
        var unaryExpression = expression.Body as UnaryExpression;
        if (unaryExpression != null)
        {
            var propertyExpression = (MemberExpression)unaryExpression.Operand;
            var parameters = expression.Parameters;

            if (propertyExpression.Type == typeof(DateTime))
            {
                var newExpression = Expression.Lambda<Func<T, DateTime>>(propertyExpression, parameters);
                return order == SortOrder.Ascending ? entities.ThenBy(newExpression) : entities.ThenByDescending(newExpression);
            }

            if (propertyExpression.Type == typeof(DateTime?))
            {
                var newExpression = Expression.Lambda<Func<T, DateTime?>>(propertyExpression, parameters);
                return order == SortOrder.Ascending ? entities.ThenBy(newExpression) : entities.ThenByDescending(newExpression);
            }

            if (propertyExpression.Type == typeof(int))
            {
                var newExpression = Expression.Lambda<Func<T, int>>(propertyExpression, parameters);
                return order == SortOrder.Ascending ? entities.ThenBy(newExpression) : entities.ThenByDescending(newExpression);
            }

            if (propertyExpression.Type == typeof(int?))
            {
                var newExpression = Expression.Lambda<Func<T, int?>>(propertyExpression, parameters);
                return order == SortOrder.Ascending ? entities.ThenBy(newExpression) : entities.ThenByDescending(newExpression);
            }

            if (propertyExpression.Type == typeof(bool))
            {
                var newExpression = Expression.Lambda<Func<T, bool>>(propertyExpression, parameters);
                return order == SortOrder.Ascending ? entities.ThenBy(newExpression) : entities.ThenByDescending(newExpression);
            }

            throw new NotSupportedException("Object type resolution not implemented for this type");
        }
        return order == SortOrder.Ascending ? entities.ThenBy(expression) : entities.ThenByDescending(expression);
    }

違いはOrderByとThenBy...であることに注意してください。残りはまったく同じです。うまくいけば、誰かがこれをリファクタリングする方法を知っています。OrderByまたはThenByメソッドを渡すためのFuncパラメーターを作成しようとしていました。しかし、私が試みるすべては私が行き詰まります。

4

1 に答える 1

1

OrderByとThenByの違いは、OrderByはIQueryableを期待し、ThenByはIOrderedqueryAbleを期待することです。

OrderByまたはThenByを使用するには、コレクションがIQueryableかIOrderedQueryAbleかを判断する必要があります。

その後、IQueryが可能な場合は、OrderByを呼び出します。IOrderedQueryableの場合は、ThenByを呼び出します(IOrderedQueryableとしてキャストした後)。

リファクタリングされたコードスニペットは

    public static IOrderedQueryable<T> ObjectSortRefactored<T>(this IQueryable<T> entities, Expression<Func<T, object>> expression, SortOrder order = SortOrder.Ascending)
    {
        var unaryExpression = expression.Body as UnaryExpression;
        if (unaryExpression != null)
        {
            var propertyExpression = (MemberExpression)unaryExpression.Operand;
            var parameters = expression.Parameters;

            if (propertyExpression.Type == typeof(DateTime))
            {
                var newExpression = Expression.Lambda<Func<T, DateTime>>(propertyExpression, parameters);
                return order == SortOrder.Ascending ? entities.OrderBy(newExpression) : entities.OrderByDescending(newExpression);
            }

            if (propertyExpression.Type == typeof(DateTime?))
            {
                var newExpression = Expression.Lambda<Func<T, DateTime?>>(propertyExpression, parameters);
                return order == SortOrder.Ascending ? entities.OrderBy(newExpression) : entities.OrderByDescending(newExpression);
            }

            if (propertyExpression.Type == typeof(int))
            {
                var newExpression = Expression.Lambda<Func<T, int>>(propertyExpression, parameters);
                return order == SortOrder.Ascending ? entities.OrderBy(newExpression) : entities.OrderByDescending(newExpression);
            }

            if (propertyExpression.Type == typeof(int?))
            {
                var newExpression = Expression.Lambda<Func<T, int?>>(propertyExpression, parameters);
                return order == SortOrder.Ascending ? entities.OrderBy(newExpression) : entities.OrderByDescending(newExpression);
            }

            if (propertyExpression.Type == typeof(bool))
            {
                var newExpression = Expression.Lambda<Func<T, bool>>(propertyExpression, parameters);
                return order == SortOrder.Ascending ? entities.OrderBy(newExpression) : entities.OrderByDescending(newExpression);
            }

            throw new NotSupportedException("Object type resolution not implemented for this type");
        }
        if(entities.GetType().IsAssignableFrom(typeof(IOrderedQueryable<T>)))
                return order == SortOrder.Ascending ? (entities as IOrderedQueryable<T>).ThenBy(expression) : (entities as IOrderedQueryable<T>).ThenByDescending(expression);

        return order == SortOrder.Ascending ? entities.OrderBy(expression) : entities.OrderByDescending(expression);
    }

ただし、上記のスニペットはテストしていません。

于 2012-05-31T14:49:58.613 に答える