将OrderBy应用于DbSet

本文关键字:DbSet 应用于 OrderBy | 更新日期: 2023-09-27 18:27:53

我正在尝试用通用存储库实现分页和排序。如何在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);
}

将OrderBy应用于DbSet

我使用了这些扩展方法来实现类似的功能:

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(GetKeyField(typeof(T))).Skip(pageNumber * pageSize)Take(pageSize);
}

这假设实体类中的键字段正确地使用Key属性进行了修饰。

一种方法是让所有实体从某个接口继承,该接口允许您检索它们的主键值:

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订购一样简单。这种模式也可以在其他方面帮助你。