Устранение перегрузки методов среди методов запросов LINQ - PullRequest
2 голосов
/ 21 июля 2010

Итак, контекст этого вопроса довольно специфичен, но я думаю, что есть общий вопрос 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 (исключая необходимость что-либо разрешать), но я бы предпочел этого не делать.

Есть еще идеи? Спасибо!

Ответы [ 2 ]

1 голос
/ 21 июля 2010

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

IQueryable<People> query = DynamicLinqHelperClass
  .OrderBy(_db.People, sortExpression)
  .Skip(startingRowIndex)
  .Take(maximumRows)
1 голос
/ 21 июля 2010

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

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

...