所以,这个问题的上下文非常具体,但我认为有一个一般的 C# 问题很难解决。 :)
我有一个 ASP.NET Web 窗体页面,其中包含绑定(bind)到 ObjectDataSource 的 GridView 控件。数据源控件 Hook 到一个数据访问类,该类又使用 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 )
(来自 Dynamic LINQ helper 类)
C# 编译器解析为第一个方法(要么因为它优先考虑非扩展方法,要么因为第一个方法在类上而不是接口(interface)上,或者我没有想到的其他一些解析逻辑), 这是行不通的:
EntitySqlException: 'Id' could not be resolved in the current scope or context.
有什么方法可以指定调用哪个重载方法(可能通过 C++ 的 ::
解析运算符)?
我意识到我可以做到这一点:
return _db.People
.AsQueryable()
.OrderBy( !string.IsNullOrWhiteSpace( sortExpression ) ? sortExpression : "Id" )
.Skip( startingRowIndex )
.Take( maximumRows )
.ToList();
但这有点丑化了我的数据访问方法。 :) 我也可以进入 Dynamic LINQ 代码并将 OrderBy 重命名为 OrderByDynamic(消除解决任何问题的需要),但我也不希望这样做。
还有其他想法吗?谢谢!
最佳答案
either because it is giving preference to the non-extension method
这是正确的假设,类的实例方法优先于扩展方法。您还已经诊断出解决该问题的可能方法。另一种选择是直接调用扩展方法(因为它只是静态类中的一个方法)。
关于c# - 解决 LINQ 查询方法中的方法重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3293918/