所以,这个问题的背景是非常具体的,但我认为有一个普遍的C#问题正在努力摆脱。 :)
我有一个ASP.NET Web窗体页面,其中GridView控件绑定到ObjectDataSource。数据源控件挂钩到数据访问类,而数据访问类又使用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控件传递给此方法的sort表达式是一个字符串,所以对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 )
(来自Dynamic LINQ帮助程序类)
C#编译器解析为第一个方法(或者是因为它优先考虑非扩展方法,或者因为第一个方法是在一个类而不是一个接口,或者是其他一些我没想过的解析逻辑),这不起作用:
EntitySqlException:'Id'不可能 在当前范围内解决或 上下文。
有没有办法指定调用哪个重载方法(可能通过类似C ++的::
解析运算符)?
我意识到我可以做到这一点:
return _db.People
.AsQueryable()
.OrderBy( !string.IsNullOrWhiteSpace( sortExpression ) ? sortExpression : "Id" )
.Skip( startingRowIndex )
.Take( maximumRows )
.ToList();
但是这有点夸大了我的数据访问方法。 :)我也可以进入动态LINQ代码并将OrderBy重命名为OrderByDynamic(无需解决任何问题),但我也不愿意这样做。
还有其他想法吗?谢谢!
答案 0 :(得分:1)
要么因为它给予优先权 到非扩展方法
这是正确的假设,类的实例方法优先于扩展方法。您还已经诊断出可能的解决方法。另一个选择是直接调用扩展方法(因为它只是静态类中的方法)。
答案 1 :(得分:1)
如果你想要更清晰的分辨率,你可以把它称为静态方法而不是扩展方法。
IQueryable<People> query = DynamicLinqHelperClass
.OrderBy(_db.People, sortExpression)
.Skip(startingRowIndex)
.Take(maximumRows)