【发布时间】:2010-07-20 20:06:18
【问题描述】:
所以,这个问题的上下文非常具体,但我认为有一个通用的 C# 问题难以摆脱。 :)
我有一个带有绑定到 ObjectDataSource 的 GridView 控件的 ASP.NET Web 窗体页面。数据源控件与数据访问类挂钩,该类又使用 LINQ 查询 Entity Framework v4。数据访问类的方法具有排序/分页参数,因此我可以使用 GridView/ObjectDataSource 控件的内置功能。这是一个例子:
public IList<Person> GetAllPaged (
string sortExpression,
int startingRowIndex,
int maximumRows )
{
return _db.People
.OrderBy( !string.IsNullOrWhiteSpace( sortExpression ) ? sortExpression : "Id" )
.Skip( startingRowIndex )
.Take( maximumRows )
.ToList();
}
由于 GridView 控件传递给该方法的排序表达式是字符串,因此对 OrderBy 的调用需要是动态的。为此,我使用了漂亮的Microsoft dynamic LINQ helper classes。
问题是 OrderBy 现在在这里重载了,其中两个重载实际上具有相同的签名:
ObjectQuery<T> OrderBy( string keys, params ObjectParameter[] parameters )
(来自 System.Data.Entity)
IQueryable OrderBy( this IQueryable source, string ordering, params object[] values )
(来自动态 LINQ 助手类)
C# 编译器解析为第一个方法(要么是因为它优先考虑非扩展方法,要么是因为第一个方法是在类与接口上,或者是我没有想到的其他解析逻辑),这不起作用:
EntitySqlException: 'Id' 不能是 在当前范围内解决或 上下文。
有什么方法可以指定调用哪个重载方法(可能通过类似 C++ 的:: 解析运算符)?
我意识到我可以这样做:
return _db.People
.AsQueryable()
.OrderBy( !string.IsNullOrWhiteSpace( sortExpression ) ? sortExpression : "Id" )
.Skip( startingRowIndex )
.Take( maximumRows )
.ToList();
但这有点丑化了我的数据访问方法。 :) 我也可以进入动态 LINQ 代码并将 OrderBy 重命名为 OrderByDynamic(无需解决任何问题),但我也不希望这样做。
还有其他想法吗?谢谢!
【问题讨论】:
标签: c# linq gridview linq-to-entities objectdatasource