简体   繁体   English

使用DbSet应用OrderBy

[英]Apply OrderBy with DbSet

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中按列的默认顺序获取主键列?

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

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. 这允许您将属性名称作为字符串传递,并构建一个表达式,并将其传递给常规LINQ OrderBy()函数。 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. 假设您的实体类中的关键字段已使用Key属性进行了适当的修饰。

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 . 然后就像Id订购一样简单。 This pattern can help you in other areas as well. 这种模式也可以帮助您在其他领域。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM