2012-05-31 2 views
0

다음 코드 조각이 있으며이 코드를 리팩터링하여 중복 코드를 제거하려고합니다. 그러나 리팩터링 할 때마다 막혔다. 이 문제로 나를 도울 수있는 사람이 있습니까?중복 코드를 제거하기 위해 리팩토링 linq 표현

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 매개 변수를 만들려고했습니다. 그러나 내가 시도하는 모든 것은 내가 붙어있다.

+1

을 왜 유형을 결정해야 할 첫 번째 코드가 각 유형에 대해 정확히 동일한 경우 먼저 메서드에 'Func '만 보내면됩니다. – mellamokb

+0

Linq? OrderBy, OrderByDescending, ThenBy, ThenByDescending에 이미 구현되지 않았습니까? – clearpath

답변

1

OrderBy와 ThenBy의 차이점은 OrderBy가 IQueryable을 예상하고 ThenBy가 IOrderedqueryAble을 예상한다는 것입니다.

이제 OrderBy 또는 ThenBy를 사용하려면 컬렉션이 IQueryable인지 IOrderedQueryAble인지 알아야합니다.

그런 다음 IQueryable 인 경우 OrderBy를 호출하십시오. 이 IOrderedQueryable 경우, IOrderedQueryable으로 캐스팅 후 ThenBy을 (호출합니다.

리팩토링 코드가

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); 
    } 

이되고 내가 비록 위의 코드를 테스트하지 않았습니다.

관련 문제