解决LINQ查询方法中的方法重载问题

时间:2010-07-20 20:06:19

标签: c# linq gridview linq-to-entities objectdatasource

所以,这个问题的背景是非常具体的,但我认为有一个普遍的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(无需解决任何问题),但我也不愿意这样做。

还有其他想法吗?谢谢!

2 个答案:

答案 0 :(得分:1)

  

要么因为它给予优先权   到非扩展方法

这是正确的假设,类的实例方法优先于扩展方法。您还已经诊断出可能的解决方法。另一个选择是直接调用扩展方法(因为它只是静态类中的方法)。

答案 1 :(得分:1)

如果你想要更清晰的分辨率,你可以把它称为静态方法而不是扩展方法。

IQueryable<People> query = DynamicLinqHelperClass
  .OrderBy(_db.People, sortExpression)
  .Skip(startingRowIndex)
  .Take(maximumRows)