如何保持lambda表达式的引用,该表达式将稍后传递给OrderBy或LoadWith函数
本文关键字:表达式 OrderBy 函数 LoadWith lambda 何保持 引用 | 更新日期: 2023-09-27 18:17:22
我正在尝试创建访问DB的一般方法。这将包含如下参数:页面索引、每页显示的项目数、排序选项、加载选项等。
...
public IQuerable<T> GetAll(int pageIndex, int itemsToDisplayPerPage, System.Linq.Expressions.Expression<Func<T,object>>[] orderBy, System.Linq.Expressions.Expression<Func<T,object>>[] loadOptions)
{
DataContext dc = null;
IQuerable<T> result = null;
// Make some initalizations
...
foreach(var item in orderBy)
{
result = result.OrderBy(item);
}
System.Data.Linq.DataLoadOptions loadOptions = new System.Data.Linq.DataLoadOptions();
foreach(var item in loadOptions)
{
loadOptions.LoadWith(item);
}
...
}
...
问题是System.Linq.Expressions.Expression< Func< T,object > >
类型并不是一个很好的lambda表达式的通用表示,对于上面的两个例子来说,它都是传递的。
On排序将崩溃,因为对象类型对排序没有任何意义。也在loadWith将不工作。所以我不知道该如何处理这个问题。有什么建议吗?谢谢你。
不确定LoadWith,因为我们正在使用linq到实体,但我们成功地使orderby在存储库Get方法中工作。客户端代码如下所示:
var results = _repository.GetAll(
new GetAllCriteria()
.OrderBy(x => x.Property1)
.OrderBy(x => x.Property2)
);
我们还没有在存储库方法中使用泛型,这可能会在将来的重构中出现。但是标准实现看起来是这样的:
public class GetAllCriteria
{
public Dictionary<Expression<Func<CustomType, object>>, bool> ToBeOrderedBy
{
get; private set;
}
public GetAllCriteria OrderBy(
Expression<Func<CustomType, object>> expression)
{
return OrderBy(expression, true);
}
public GetAllCriteria OrderByDescending(
Expression<Func<CustomType, object>> expression)
{
return OrderBy(expression, false);
}
private GetAllCriteria OrderBy(
Expression<Func<CustomType, object>> expression, bool isAscending)
{
if (expression != null)
{
if (ToBeOrderedBy == null)
ToBeOrderedBy = new Dictionary<Expression<Func<CustomType, object>>, bool>();
ToBeOrderedBy.Add(expression, isAscending);
}
return this;
}
}
然后,存储库命令如下:
public Collection<CustomType> GetAll(GetAllCriteria criteria)
{
var query = dbContext.CustomTypes.AsQueryable();
// some code
// apply order by
if (criteria.ToBeOrderedBy != null && criteria.ToBeOrderedBy.Count > 0)
{
var firstOrderBy = criteria.ToBeOrderedBy.First();
query = firstOrderBy.Value
? query.OrderBy(firstOrderBy.Key)
: query.OrderByDescending(firstOrderBy.Key);
query = criteria.ToBeOrderedBy.Skip(1).Aggregate(query,
(lastOrderBy, nextOrderBy) => nextOrderBy.Value
? ((IOrderedQueryable<CustomType>)lastOrderBy)
.ThenBy(nextOrderBy.Key)
: ((IOrderedQueryable<CustomType>)lastOrderBy)
.ThenByDescending(nextOrderBy.Key));
}
// some more code
var results = query.ToList();
return results;
}
如果这适用于linq到实体,我想它应该适用于linq到sql。