2014-10-15 2 views
0

nullable 필드를 정렬하는 ASP.NET 페이지를 작성하려고합니다. 내가 할 수있는 일은 sortable 필드에 null 값이 있으면 항상 해당 행을 목록의 끝에 던져 버리는 것입니다. 그렇지 않으면, 그들은 목록의 시작 부분에 나타나고, A-Z 정렬 요소에 도달하기 전에 널 값 행의 페이지와 페이지를 상상할 수 있습니다.정렬을 사용한 동적 Linq 쿼리, 끝 nulls

저는 ASP.NET 프레임 워크에서 작업하고 있습니다. 나는이 프레임 워크 내에서 작업하고 있기 때문에, 나는이 기능이 작동하는 방식을 변경하지 않을거야

public static class QueryExtensions { 
public static IQueryable<T> SortBy<T>(this IQueryable<T> source, string propertyName) { 
    if (source == null) { 
     throw new ArgumentNullException("source"); 
    } 
    // DataSource control passes the sort parameter with a direction 
    // if the direction is descending   
    int descIndex = propertyName.IndexOf(" DESC"); 
    if (descIndex >= 0) { 
     propertyName = propertyName.Substring(0, descIndex).Trim(); 
    } 

    if (String.IsNullOrEmpty(propertyName)) { 
     return source; 
    } 

    ParameterExpression parameter = Expression.Parameter(source.ElementType, String.Empty); 
    MemberExpression property = Expression.Property(parameter, propertyName); 
    LambdaExpression lambda = Expression.Lambda(property, parameter); 

    string methodName = (descIndex < 0) ? "OrderBy" : "OrderByDescending"; 

    Expression methodCallExpression = Expression.Call(typeof(Queryable), methodName, 
             new Type[] { source.ElementType, property.Type }, 
             source.Expression, Expression.Quote(lambda)); 

    return source.Provider.CreateQuery<T>(methodCallExpression); 
} 

}

: 정렬 열에 대한 해결책은 여기에있는 GridViewDataSource에 대한 동적 쿼리를 구축하는 것입니다. 대신,이 서명 방법을 과부하하는 것을 시도하고있다 :

public static IQueryable<T> SortBy<T>(this IQueryable<T> source, string propertyName, bool nullsToEnd) 

오전 데 문제를 내가 널 (null)와 (특히 정렬 이러한 유형의 수 있도록 AZ를 'methodName로'를 편집하는 방법을 알아낼 수있다 결국) 일어날 것입니다.

트릭을 어떻게 할 것인가에 대한 아이디어가 있습니까?

감사합니다.

답변

2

나는 당신이 원하는 것을 할 방법 이름 자체가 있다고 생각하지 않습니다. 대신이 시나리오에서는 사용자 지정 IComparer 인스턴스를 사용하는 다른 메서드 오버로드를 선택해야합니다. 그런 다음 Comparer.Default를 감싸는 IComparer를 구현하고, null이 관련되지 않은 경우 해당 비교 자의 결과를 반환하고, 널 (null)이있을 때 끝에 정렬합니다.

OrderBy 및 OrderByDescending의 경우 모두 끝에 null이 필요하면 그에 따라 IComparer 구현을 조정해야합니다. 둘 다 nulls 및 오름차순/내림차순 옵션을 모두 처리 할 또는 "내림차순"대/소문자를 수행 할 때 처음에 nulls 정렬 할 (개인적으로, IComparer 오름차순/내림차순 상태를 기반으로 조정해야하므로, 나는 앞으로 나아가서 IComparer가 오름차순/내림차순 부분도 처리하도록 할 것이다). 예를 들어

다음 "널 (null) 마지막에있는"시나리오에 대한 그런

class NullsAtEndComparer<T> : IComparer<T> where T : class 
{ 
    private static readonly IComparer<T> _baseComparer = Comparer<T>.Default; 

    private readonly bool _ascending; 

    public NullsAtEndComparer(bool ascending = true) 
    { 
     _ascending = ascending; 
    } 

    public int Compare(T t1, T t2) 
    { 
     if (object.ReferenceEquals(t1, t2)) 
     { 
      return 0; 
     } 

     if (t1 == null) 
     { 
      return 1; 
     } 

     if (t2 == null) 
     { 
      return -1; 
     } 

     return _ascending ? _baseComparer.Compare(t1, t2) : _baseComparer.Compare(t2, t1); 
    } 
} 

, 그냥 항상있는 OrderBy 방법을 사용하는 방법에 대해 위의 IComparer 구현의 인스턴스를 제공합니다.

+0

정렬 버그를 수정 한 내 편집에 유의하십시오. 비교 자 (comparator)는 둘 모두가 널 (null)이더라도 입력의 모든 동일한 쌍을 동일한 것으로 간주해야합니다. object.ReferenceEquals()를 사용하면이 작업을 수행 할 수 있으며 동일한 피연산자가 두 피연산자로 전달되는 경우 바로 가기 최적화를 제공합니다. –