我如何才能保持稍后将传递到排序依据或LoadWith功能的lambda表达式的参考? [英] How can i keep reference of a lambda expression that will be later passed to OrderBy or LoadWith functions?
问题描述
我想创建用于访问数据库的一般方法。这将意味着像参数:页面索引,项目每页显示的数量,订购选项,加载选项等
I am trying to create a general method for accessing the DB. This will imply parameters like: page index, number of items to display per page, ordering options, load options etc.
...
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,对象>方式>
类型不是将上面的两个例子可以通过任何lambda表达式的一个很好的一般表示。
The problem is that the System.Linq.Expressions.Expression< Func< T,object > >
type is not a good general representation of any lambda expression that will be passed for the both examples above.
在订货会崩溃,因为的对象类型没有任何意义的顺序。同样在loadWith将无法正常工作。所以我不知道如何处理这个问题。有什么建议么?谢谢你。
On ordering will crash because of the object type that does not make any sense for ordering. Also on loadWith will not work. So i dont know how can i handle this problem. Any suggestions? Thank you.
推荐答案
不知道的LoadWith,因为我们使用LINQ到实体,但我们成功拿到排序依据的工作中存储库获取方法。客户端代码如下:
Not sure about the LoadWith, as we are using linq to entities, but we successfully got orderby to work in a repository Get method. The client code looks like this:
var results = _repository.GetAll(
new GetAllCriteria()
.OrderBy(x => x.Property1)
.OrderBy(x => x.Property2)
);
我们不使用泛型方法库,只是还没有,这可能会在未来的重构。但是,标准的实施看起来是这样的:
We aren't using generics in repository methods just yet, that will probably come in a future refactor. But the criteria implementation looks like this:
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;
}
}
然后,库订单像这样:
Then, the repository orders like so:
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。
If this works with linq to entities, I would imagine it should work with linq to sql.
这篇关于我如何才能保持稍后将传递到排序依据或LoadWith功能的lambda表达式的参考?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!