以下是我使用此方法来建立具有分页和排序功能的动态linq查询的方法。但是,当通过与其他实体(例如,实体产品)有关系的属性进行发送排序时,与客户有关系,并且调用获取客户的方法,并且在“ includeProperties”中发送产品,而我希望通过“ Product.Name”进行排序。它没用
方法:
public virtual IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "", int page = 0, int pagesize = 100, string sortColumn = "", string sortColumnDir = "")
{
IQueryable<TEntity> query = dbSet;
if (filter != null)
{
query = query.Where(filter);
}
foreach (var includeProperty in includeProperties.Split
(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProperty);
}
if (sortColumn != string.Empty && sortColumn.IndexOf(".") <= 0)
{
ParameterExpression[] typeParams = new ParameterExpression[] {
Expression.Parameter(typeof(TEntity), "")
};
System.Reflection.PropertyInfo pi = typeof(TEntity).GetProperty(sortColumn);
sortColumnDir = sortColumnDir == "asc" ? "OrderBy" : "OrderByDescending";
query = (IOrderedQueryable<TEntity>)query.Provider.CreateQuery(
Expression.Call(
typeof(Queryable),
sortColumnDir,
new Type[] { typeof(TEntity), pi.PropertyType },
query.Expression,
Expression.Lambda(Expression.Property(typeParams[0], pi), typeParams))
);
}
else if (orderBy != null)
{
query = orderBy(query);
}
else
{
query = query.OrderBy(obj => obj.Desativado);
}
query = query.Skip(page * pagesize).Take(pagesize);
return query.ToList();
}
有人可以帮助我吗?
答案 0 :(得分:0)
当您在"X.Y"
参数中传递类似sortColumn
的内容时,查询生成器方法会做什么?
首先尝试
if (sortColumn != string.Empty && sortColumn.IndexOf(".") <= 0)
当您在sortColumn
中有一个点时,条件的计算结果为false。因此该分支将被跳过。
然后来
else if (orderBy != null)
这不再是成功,您没有提供orderBy
,而是提供了sortColumn
参数。
所以最后你得到了
else
{
query = query.OrderBy(obj => obj.Desativado);
}
这显然与您要实现的目标相去甚远,因为它根本无法按X.Y
进行排序。
那该怎么办?您必须选择:
您使用回调而不是路径字符串定义排序:
ProductRepository.Get(p => p.Name == "X", includeProperties: "Item", orderBy: query => query.OrderBy(product => product.Item.Codigo))
您可以更改查询生成器方法,以使其接受sortColumn
中的属性路径。不过,这需要更多的努力。