2014-10-24 11 views
6

Sto cercando di implementare l'impaginazione e l'ordinamento con repository generico. Come prendere la colonna della chiave primaria come ordine per colonna in DbSet?Applica ordine con 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

lato nota, sono abbastanza sicuro che si vorrà '' Skip' poi Take' – Jonesopolis

+0

@Jonesy, Sì grazie, cambiato ... –

risposta

6

Ho usato questi metodi di estensione per ottenere qualcosa di simile:

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

Questo permette di passare il nome della proprietà come una stringa e costruire un'espressione che si passa alla normale LINQ OrderBy () funzione. Quindi nel tuo caso, l'utilizzo potrebbe essere:

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

Questo presuppone che il campo chiave nella classe entità è adeguatamente decorata con l'attributo Key.

+0

+1, uno molto utile ... –

+1

soluzione grande e flessibile, salvato ho un sacco di tempo. Grazie! – Oleg

+0

Funziona come un fascino. Grazie! –

0

Un modo potrebbe essere quello di avere tutte le entità ereditano da qualche interfaccia che consente di recuperare il loro valore della chiave primaria:

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

Poi sarebbe implementazioni come:

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

    //other properties... 

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

allora sarebbe facile come ordinare da Id. Questo modello può aiutarti anche in altre aree.