问题
I am trying to implement pagination and sorting with generic repository. How to take primary key column as default order by column in 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);
}
回答1:
I have used these extension methods to achieve something similar:
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);
}
This allows you to pass the property name as a string and build up an expression which it passes to the regular LINQ OrderBy() function. So in your case, the usage would be:
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);
}
This assumes your key field in your entity class is properly decorated with the Key
attribute.
回答2:
One way would be to have all your entities inherit from some interface that allows you to retrieve their primary key value :
public interface IIdentifiableEntity
{
public int Id {get; set;}
}
Then implementations would be like :
public class User : IIdentifiableEntity
{
public int UserId {get; set;}
//other properties...
public int Id { get { return UserId; } set { UserId = value; } }
}
Then it would be as easy as ordering by the Id
. This pattern can help you in other areas as well.
来源:https://stackoverflow.com/questions/26550930/apply-orderby-with-dbset