我正在使用 T4 为 LINQ to Entities 实体生成存储库。
存储库包含(除其他外)适合分页的 List 方法。Supported and Unsupported Methods的文档没有提到它,但你不能Skip
在 unordered 上“调用” IQueryable
。它将引发以下异常:
System.NotSupportedException:方法“Skip”仅支持 LINQ to Entities 中的排序输入。方法 'OrderBy' 必须在方法 'Skip' 之前调用。
我通过允许通过部分方法定义默认排序来解决它。但是我在检查表达式树是否确实包含OrderBy
.
我已将问题减少到尽可能少的代码:
public partial class Repository
{
partial void ProvideDefaultSorting(ref IQueryable<Category> currentQuery);
public IQueryable<Category> List(int startIndex, int count)
{
IQueryable<Category> query = List();
ProvideDefaultSorting(ref query);
if (!IsSorted(query))
{
query = query.OrderBy(c => c.CategoryID);
}
return query.Skip(startIndex).Take(count);
}
public IQueryable<Category> List(string sortExpression, int startIndex, int count)
{
return List(sortExpression).Skip(startIndex).Take(count);
}
public IQueryable<Category> List(string sortExpression)
{
return AddSortingToTheExpressionTree(List(), sortExpression);
}
public IQueryable<Category> List()
{
NorthwindEntities ent = new NorthwindEntities();
return ent.Categories;
}
private Boolean IsSorted(IQueryable<Category> query)
{
return query is IOrderedQueryable<Category>;
}
}
public partial class Repository
{
partial void ProvideDefaultSorting(ref IQueryable<Category> currentQuery)
{
currentQuery = currentQuery.Where(c => c.CategoryName.Contains(" ")); // no sorting..
}
}
这不是我真正的实现!
但我的问题是,我该如何实现该IsSorted
方法?问题是 LINQ to Entities 查询始终是类型ObjectQuery
,它实现了IOrderedQueryable
.
那么我应该如何确保OrderBy
表达式树中存在方法呢?是解析树的唯一选择吗?
更新
我添加了另外两个重载以明确这不是关于如何向存储库添加排序支持,而是如何检查ProvideDefaultSorting
部分方法是否确实向OrderBy
表达式树添加了一个。
问题是,第一个部分类是由模板生成的,而部分类的第二部分的实现是由团队成员在另一个时间完成的。您可以将其与 .NET Entity Framework 生成 EntityContext 的方式进行比较,它允许为其他开发人员提供扩展点。因此,我想尝试使其健壮,并且在ProvideDefaultSorting
未正确实施时不会崩溃。
所以也许问题更多,我怎样才能确认ProvideDefaultSorting
确实向表达式树添加了排序。
更新 2
新问题已得到回答并被接受,我想我应该更改标题以更匹配问题。或者我应该留下当前的标题,因为它会引导有同样问题的人使用这个解决方案?