【发布时间】:2008-10-22 12:06:33
【问题描述】:
我正在使用 T4 为 LINQ to Entities 实体生成存储库。
存储库包含(除其他外)一个适合分页的 List 方法。 Supported and Unsupported Methods 的文档没有提到它,但你不能在无序的 IQueryable 上“调用”Skip。它将引发以下异常:
System.NotSupportedException:方法“Skip”仅支持 LINQ to Entities 中的排序输入。必须先调用方法“OrderBy” 方法“跳过”..
我通过允许通过部分方法定义默认排序来解决它。但我在检查表达式树是否确实包含 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
新问题已得到回答并被接受,我认为我应该更改标题以更匹配问题。还是我应该保留当前标题,因为它会引导有相同问题的人使用此解决方案?
【问题讨论】:
标签: c# linq generics linq-to-entities code-generation