Разрешение перегрузки метода среди методов запроса LINQ

Итак, контекст этого вопроса довольно специфичен, но я думаю, что есть общий вопрос C #, который изо всех сил пытается выйти. :)

У меня есть страница веб-форм ASP.NET с элементом управления 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, является строкой, вызов OrderBy должен быть динамическим. С этой целью я использую отличный Динамические вспомогательные классы Microsoft LINQ.

Проблема в том, что 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();

Но это немного усложняет мои методы доступа к данным. :) Я также мог бы перейти к коду Dynamic LINQ и переименовать OrderBy в OrderByDynamic (устранив необходимость что-либо разрешать), но я бы тоже предпочел этого не делать.

Любые другие идеи? Спасибо!


person Matt Peterson    schedule 20.07.2010    source источник


Ответы (2)


либо потому, что он отдает предпочтение методу без расширения

Это правильная гипотеза, методы экземпляра класса имеют преимущество перед методом расширения. Вы также уже диагностировали возможные способы обойти это. Другой вариант - возможно, вызвать метод расширения напрямую (поскольку это просто метод в статическом классе).

person Anthony Pegram    schedule 20.07.2010

Если вам нужно более четкое разрешение, вы можете просто вызвать его как статический метод, а не как метод расширения.

IQueryable<People> query = DynamicLinqHelperClass
  .OrderBy(_db.People, sortExpression)
  .Skip(startingRowIndex)
  .Take(maximumRows)
person Amy B    schedule 20.07.2010