【发布时间】:2021-03-05 11:06:21
【问题描述】:
我有一个如下的存储库类。我的问题出在 GetSelected 方法中
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
protected readonly DbContext Db;
protected readonly DbSet<TEntity> DbSet;
public Repository(DbContext context)
{
Db = context;
DbSet = Db.Set<TEntity>();
}
//CRUD Operations
public IEnumerable<TEntity> GetSelected(Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, params Expression<Func<TEntity, object>>[] includeProperties)
{
IQueryable<TEntity> query = DbSet;
if (filter != null)
{
query = query.Where(filter);
}
foreach (var includeProperty in includeProperties)
{
query = query.Include(includeProperty);
}
if (orderBy != null)
{
return orderBy(query).ToList();
}
else
{
return query.ToList();
}
}
}
我正在尝试通过动态提供参数来对部门进行排序,如下所示。
[Route("api/[controller]")]
[ApiController]
public class DepartmentsController : LookupBaseController<Department>
{
private readonly IUowLookups UowLookups;
public DepartmentsController(IUowLookups uowLookups) : base(uowLookups)
{
UowLookups = uowLookups;
}
[HttpPost] //Improvise on this
[Route("getorderd")]
public IEnumerable<Department> GetSelectedValues(List<string> ids)
{
var sortColumns = new Dictionary<string, Sorter>();
sortColumns.Add("Code", new Sorter(1, SortDirection.Ascending));
sortColumns.Add("Name", new Sorter(2, SortDirection.Ascending));
IQueryable<Department> coll = Enumerable.Empty<Department>().AsQueryable();
var sortExp2 = ExpressionBuilder.OrderByColumns<Department>(coll, sortColumns);
var data = UowLookups.Repository<Department>().GetSelected(null, sortExp2 )
return data.ToList();
}
}
我有以下运行良好的代码(在 StackOverflow 中找到)。但我希望以下代码返回 (Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>>) 而不是集合。我也不想将集合传递给这个方法,相反,它应该将TEntity 作为集合传递。可行吗?
public static IQueryable<TEntity> OrderByColumns<TEntity>(this IQueryable<TEntity> collection, IDictionary<string, Sorter> sortedColumns)
{
// Basically sortedColumns contains the columns user wants to sort by, and
// the sorting direction.
// For my screenshot, the sortedColumns looks like
// [
// { "cassette", { Order = 1, Direction = SortDirection.Ascending } },
// { "slotNumber", { Order = 2, Direction = SortDirection.Ascending } }
// ]
bool firstTime = true;
// The type that represents each row in the table
var itemType = typeof(TEntity);
// Name the parameter passed into the lamda "x", of the type TModel
var parameter = Expression.Parameter(itemType, "x");
// Loop through the sorted columns to build the expression tree
foreach (var sortedColumn in sortedColumns.OrderBy(sc => sc.Value.Order))
{
// Get the property from the TModel, based on the key
var prop = Expression.Property(parameter, sortedColumn.Key);
// Build something like x => x.Cassette or x => x.SlotNumber
var exp = Expression.Lambda(prop, parameter);
// Based on the sorting direction, get the right method
string method = String.Empty;
if (firstTime)
{
method = sortedColumn.Value.Direction == SortDirection.Ascending
? "OrderBy"
: "OrderByDescending";
firstTime = false;
}
else
{
method = sortedColumn.Value.Direction == SortDirection.Ascending
? "ThenBy"
: "ThenByDescending";
}
// itemType is the type of the TModel
// exp.Body.Type is the type of the property. Again, for Cassette, it's
// a String. For SlotNumber, it's a Double.
Type[] types = new Type[] { itemType, exp.Body.Type };
// Build the call expression
// It will look something like:
// OrderBy*(x => x.Cassette) or Order*(x => x.SlotNumber)
// ThenBy*(x => x.Cassette) or ThenBy*(x => x.SlotNumber)
var mce = Expression.Call(typeof(Queryable), method, types,
collection.Expression, exp);
// Now you can run the expression against the collection
collection = collection.Provider.CreateQuery<TEntity>(mce);
}
return collection;
}
【问题讨论】:
-
这是一个非常奇怪的请求,感觉像是 XY 问题。你到底想达到什么目的?
-
我有一个 Repository
类,它的 GetData 方法接受参数 Func , IOrderedQueryable > orderBy。我想将上述函数(集合)的结果作为参数 orderBy 的参数值传递给该方法(GetData)。 -
发布使用示例。字数不够。
-
您好 Danyliv,感谢您为我提供的帮助。我有一个 Repository 类,其方法如下
-
@Jacob,只需编辑原始问题并添加使用示例。
标签: c# linq expression-trees