views:

50

answers:

2

So, the context of this question is pretty specific, but I think there is a general C# question struggling to get out. :)

I have an ASP.NET Web Forms page with a GridView control bound to an ObjectDataSource. The data source control is hooked to a data access class that, in turn, uses LINQ to query Entity Framework v4. The methods on the data access class have sorting/paging parameters so I can use the built-in capabilities of the GridView/ObjectDataSource controls. Here is an example:

public IList<Person> GetAllPaged (
    string sortExpression,
    int startingRowIndex,
    int maximumRows )
{
    return _db.People
        .OrderBy( !string.IsNullOrWhiteSpace( sortExpression ) ? sortExpression : "Id" )
        .Skip( startingRowIndex )
        .Take( maximumRows )
        .ToList();
}

Because the sort expression passed to this method by the GridView control is a string, the call to OrderBy needs to be dynamic. To that end, I'm using the nifty Microsoft dynamic LINQ helper classes.

The problem is that OrderBy is now overloaded here, and two of the overloads have effectively the same signature:

ObjectQuery<T> OrderBy( string keys, params ObjectParameter[] parameters )

(from System.Data.Entity)

IQueryable OrderBy( this IQueryable source, string ordering, params object[] values )

(from the Dynamic LINQ helper classes)

The C# compiler resolves to the first method (either because it is giving preference to the non-extension method, or because the first method is on a class vs. an interface, or some other resolution logic I'm not thinking of), which doesn't work:

EntitySqlException: 'Id' could not be resolved in the current scope or context.

Is there any way to specify which overloaded method is called (maybe via something like C++'s :: resolution operator)?

I realize that I could do this:

return _db.People
    .AsQueryable()
    .OrderBy( !string.IsNullOrWhiteSpace( sortExpression ) ? sortExpression : "Id" )
    .Skip( startingRowIndex )
    .Take( maximumRows )
    .ToList();

But that uglifies my data access methods a bit. :) I also could go into the Dynamic LINQ code and rename OrderBy to OrderByDynamic (eliminating the need to resolve anything), but I'd prefer not to do that, either.

Any other ideas? Thanks!

+1  A: 

either because it is giving preference to the non-extension method

This is the correct hypothesis, instance methods of a class are given preference over an extension method. You have also already diagnosed possible means of getting around that. Another option is to perhaps call the extension method directly (as it is just a method in a static class).

Anthony Pegram
+1  A: 

If you want clearer resolution, you could just call it like a static method instead of an extension method.

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