我正在尝试创建访问数据库的通用方法。这将暗示参数,例如:页面索引,每页显示的项目数,订购选项,加载选项等。
...
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表达式。由于对象类型对于订购没有意义,因此在订购时会崩溃。同样在loadWith上将不起作用。所以我不知道我该怎么处理这个问题。有什么建议么?谢谢。
最佳答案
由于我们对实体使用linq,因此不确定LoadWith,但是我们成功地使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一起工作。
关于c# - 如何保留对稍后将传递给OrderBy或LoadWith函数的lambda表达式的引用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8438625/