【问题标题】:Extension method not showing up扩展方法未显示
【发布时间】:2014-05-07 14:49:24
【问题描述】:

我需要有关如何在我的 ASP.Net MVC 控制器中显示我的第二个扩展方法“OrderBy”(如下所示)的帮助。

第一个扩展方法“Where”出现了,但没有出现“OrderBy”。我需要做什么才能让它出现?或者我的代码在第二种扩展方法中是错误的?

注意:我已经通过添加将命名空间导入到我的控制器中:

using MyApplication.Models;

这是我的扩展方法代码:

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);
        }
    }
}

这是控制器中的代码:

using MyApplication.Models;

...

using (MyContext context = new MyContext())
{

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

非常感谢任何帮助。

-马克


编辑:

这是我的新 OrderBy 扩展方法:

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);
    }

【问题讨论】:

    标签: c# asp.net-mvc-4 extension-methods


    【解决方案1】:

    问题是您的扩展方法有两个类型参数,但编译器只能在类型推断中使用其中一个 - TKey 在普通参数列表中根本没有提及,这是在类型推断。

    我怀疑这会找到你的扩展方法:

    // 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);
    

    这在使用方面可能并不理想,但至少它可以引导您朝着正确的方向前进,说明它为什么不起作用。如果您想依赖类型推断,则需要摆脱 TKey 作为类型参数,而是通过反射找出它 - 然后执行其余的逻辑。

    【讨论】:

    • 你能重写Op orderby函数吗?不幸的是我没明白你的意思
    • @EhsanSajjad:我不明白你的意思——我已经更改了 calling 代码,让它能够使用扩展方法;扩展方法根本不需要改变。
    • 在调用你放置属性的地方会准确传递什么?
    • @EhsanSajjad:对不起,我完全不明白那个评论。我所做的只是复制 OP 之前 trying 调用扩展方法的代码,并添加类型参数。 (我猜到了string 部分。我会在我的回答中澄清这一点。)
    • @EhsanSajjad:这些是泛型类型参数。这就像你指定一个类型参数来构造一个字符串列表:var x = new List&lt;string&gt;()。尖括号中的两种类型是类型参数; property 是一个常规参数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多