2014-10-24 2 views
6

일반 저장소를 사용하여 페이지 매김 및 정렬을 구현하려고합니다. DbSet에서 기본 키 열을 기본 순서로 가져 오는 방법?DbSet을 사용하여 OrderBy 적용

public static string GetKeyField(Type type) 
{ 
    var allProperties = type.GetProperties(); 

    var keyProperty = allProperties.SingleOrDefault(p => p.IsDefined(typeof(KeyAttribute))); 

    return keyProperty != null ? keyProperty.Name : null; 
} 

public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string orderBy) 
{ 
    return source.GetOrderByQuery(orderBy, "OrderBy"); 
} 

public static IQueryable<T> OrderByDescending<T>(this IQueryable<T> source, string orderBy) 
{ 
    return source.GetOrderByQuery(orderBy, "OrderByDescending"); 
} 

private static IQueryable<T> GetOrderByQuery<T>(this IQueryable<T> source, string orderBy, string methodName) 
    { 
     var sourceType = typeof(T); 
     var property = sourceType.GetProperty(orderBy); 
     var parameterExpression = Expression.Parameter(sourceType, "x"); 
     var getPropertyExpression = Expression.MakeMemberAccess(parameterExpression, property); 
     var orderByExpression = Expression.Lambda(getPropertyExpression, parameterExpression); 
     var resultExpression = Expression.Call(typeof(Queryable), methodName, 
               new[] { sourceType, property.PropertyType }, source.Expression, 
               orderByExpression); 

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

이것은 당신이 문자열로 속성 이름을 전달하고 일반 LINQ있는 OrderBy에 전달하는 식을 구축 할 수 있습니다 (:

DbSet = Context.Set<T>(); 

public IQueryable<T> GetAll(int pageNumber = 0, int pageSize = 10, string sortColumn = "") 
{ 
    return DbSet.OrderBy("how to use primary key column here").Skip(pageNumber * pageSize)Take(pageSize); 
} 
+0

사이드 노트, 나는'Take '를 Skip하고 싶을 것이라고 확신한다. – Jonesopolis

+0

@Jonesy, Yes Thanks, changed ... –

답변

6

나는 비슷한 달성하기 위해 이러한 확장 방법을 사용했다) 기능. 귀하의 경우 그래서, 사용은 다음과 같습니다

DbSet = Context.Set<T>(); 

public IQueryable<T> GetAll(int pageNumber = 0, int pageSize = 10, string sortColumn = "") 
{ 
    return DbSet.OrderBy(GetKeyField(typeof(T))).Skip(pageNumber * pageSize)Take(pageSize); 
} 

이 제대로 Key 속성으로 장식하여 엔티티 클래스에 키 필드를 가정합니다.

+0

+1, 매우 유용한 것 ... –

+1

위대하고 유연한 해결책 나에게 많은 시간을. 고맙습니다! – Oleg

+0

매력처럼 작동합니다. 고맙습니다! –

0

한 가지 방법은 모든 기관이 당신의 주요 키 값을 검색 할 수 있도록 일부 인터페이스에서 상속해야하는 것입니다 :

public interface IIdentifiableEntity 
{ 
    public int Id {get; set;} 
} 

그런 다음 구현 될 것 같은 그런 다음

public class User : IIdentifiableEntity 
{ 
    public int UserId {get; set;} 

    //other properties... 

    public int Id { get { return UserId; } set { UserId = value; } } 
} 

는 것 Id으로 주문하는 것만 큼 쉬워야합니다. 이 패턴은 다른 영역에서도 도움이 될 수 있습니다.

관련 문제