2014-10-24 13 views
6

Tôi đang cố triển khai phân trang và sắp xếp với kho lưu trữ chung. Làm cách nào để lấy cột khóa chính làm thứ tự mặc định theo cột trong DbSet?Áp dụng OrderBy với DbSet

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

lưu ý phụ, tôi chắc chắn bạn sẽ muốn 'Bỏ qua 'rồi' Take' – Jonesopolis

+0

@Jonesy, Có Cảm ơn, đã thay đổi ... –

Trả lời

6

Tôi đã sử dụng những phương pháp mở rộng để đạt được một cái gì đó tương tự:

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

này cho phép bạn vượt qua các tên thuộc tính như là một chuỗi và xây dựng một biểu thức mà nó đi đến thường xuyên LINQ OrderBy () chức năng. Vì vậy, trong trường hợp của bạn, việc sử dụng sẽ là:

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

này giả định lĩnh vực then chốt của bạn trong lớp thực thể của bạn được trang trí đúng cách với các thuộc tính Key.

+0

+1, rất hữu ích ... –

+1

Giải pháp tuyệt vời và linh hoạt, được lưu tôi rất nhiều thời gian. Cảm ơn bạn! – Oleg

+0

Làm việc như một sự quyến rũ. Cảm ơn bạn! –

0

Một cách sẽ có tất cả các đơn vị của bạn kế thừa từ một số giao diện cho phép bạn để lấy giá trị khóa chính của họ:

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

Sau đó triển khai sẽ như thế nào:

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

    //other properties... 

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

Sau đó, nó sẽ dễ dàng như đặt hàng theo số Id. Mẫu này cũng có thể giúp bạn trong các lĩnh vực khác.