Domanda

I need help on how to show up my 2nd extension method "OrderBy" (shown below) in my ASP.Net MVC Controller.

The 1st extension method "Where" is showing up but not "OrderBy". What do i need to do to make it show up? Or maybe my code is wrong in the 2nd extension method?

NOTE: I have already imported the namespace in my controller by adding:

using MyApplication.Models;

Here's my code for the extension methods:

namespace MyApplication.Models
{
    public static class ExtensionMethods
    {
        public static IQueryable<T> Where<T>(this IQueryable<T> source, string     columnName, string value, string filterType)
        {

        ParameterExpression table = Expression.Parameter(typeof(T), "x");
        MemberExpression column = Expression.PropertyOrField(table, columnName);
        Expression valueExpression = null;
        Expression where = null;

        if (column.Type.FullName.Contains("String")) {...}
        if (column.Type.FullName.Contains("Int32")) {...}
        if (column.Type.FullName.Contains("DateTime")){...}

        var predicate = Expression.Lambda<Func<T, bool>>(where, table);

        return source.Where(predicate);
        }

        public static IOrderedQueryable<T> OrderBy<T,TKey>(this IQueryable<T> source,   string columnName)
        {
            ParameterExpression table = Expression.Parameter(typeof(T), "x");
            Expression column = Expression.PropertyOrField(table, columnName);
            var keySelector = Expression.Lambda<Func<T, TKey>>(column,table);
            return source.OrderBy(keySelector);
        }
    }
}

Here's the code in the Controller:

using MyApplication.Models;

...

using (MyContext context = new MyContext())
{

    IQueryable<Shipper> query = context.Shippers;
    query = query.Where(property,value,filterType);
    query = query.OrderBy(property);
}

Any help is greatly appreciated.

-Mark


EDIT:

Here's my new OrderBy extension method:

public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string columnName, bool asc)
    {
        var entityType = typeof(T);
        var property = entityType.GetProperty(columnName);
        ParameterExpression table = Expression.Parameter(entityType, "x");
        Expression column = Expression.PropertyOrField(table, columnName);

        string sortMethod="";

        if (asc) { sortMethod = "OrderBy"; }
        else { sortMethod = "OrderByDescending"; }

        var keySelector = Expression.Lambda(column,table);

        MethodCallExpression resultExp = Expression.Call(
            typeof(Queryable),
            sortMethod,
            new Type[] { entityType, property.PropertyType },
            source.Expression,
            Expression.Quote(keySelector));

        return (IOrderedQueryable<T>)source.Provider.CreateQuery<T>(resultExp);
    }
È stato utile?

Soluzione

The problem is that your extension method has two type parameters, but only one of them can be used in type inference by the compiler - TKey isn't mentioned at all in the normal parameter list, which is what's used in type inference.

I suspect this would find your extension method:

// Of course I don't know that it's meant to be string. You should use whatever
// type is appropriate.
query = query.OrderBy<Shipper, string>(property);

That may not be ideal in terms of usage, but at least it steers you in the right direction in terms of why it wasn't working. If you want to rely on type inference, you'll need to get rid of TKey as a type parameter, instead figuring that out - and then performing the rest of your logic - with reflection.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top