0

我的通用存储库中有以下方法,可以按字段名称排序。我需要知道如何才能通过多个字段订购它。

public IList<TEntity> FindByExpressionOrdered(Expression<Func<TEntity, bool>> filter,
                                                params Expression<Func<TEntity, object>>[] orderBy)
{
    IOrderedQueryable<TEntity> query = SessionScope.Current.Set<TEntity>().Where(filter).OrderBy(orderBy.First());
    if (orderBy.Length > 1)
    {
        for (int i = 1; i < orderBy.Length; i++)
        {
            query = query.ThenBy(orderBy[i]);
        }
    }
    return query.ToList();
}

如下调用上述代码会导致“无法将类型 'System.Int64' 转换为类型 'System.Object'。LINQ to Entities 仅支持转换实体数据模型原始类型。” 例外。

IList<Product> prods = IoC.Resolve<IRepository<Product>>().FindByExpressionOrdered(p => p.IsActive && p.IsFavorite, p => p.Name, p => p.Id);
4

1 回答 1

1

You can use Expression<Func<TEntity, object>> for ordering expressions, it should work fine.

Then just change your method to

public IList<TEntity> FindByExpression(Expression<Func<TEntity, bool>> filter,
                                                    Expression<Func<TEntity, object>> subSelector,
                                                    params Expression<Func<TEntity, object>>[] orders)
{
    var query = SessionScope.Current.Set<TEntity>().Include(subSelector).Where(filter).OrderBy(m => true);
    query = orders.Aggregate(query, (current, order) => current.ThenBy(order));

    return query.ToList();
}

But one day, you'll want to choose the order direction... And will have to find a more clever way !

without the "OrderBy(m => true") trick, and with your comment (and with the same problem, if orderBy params is an empty array, this will fail) , I would do

var query = SessionScope.Current.Set<TEntity>()
                        .Include(subSelector)
                        .Where(filter)
                        .OrderBy(orderBy.First());
foreach (var order in orderBy.Skip(1))
   query = query.OrderBy(order);
于 2013-02-02T23:46:15.377 回答