直接调用方法——MakeGenericMethod

Call method directly - MakeGenericMethod

我用这个答案写了下面的代码: LINQ to Entities does not recognize the method 'Method name' method

    /// <summary>
    /// Helper class to assit with ordering
    /// </summary>
    public static class QueryableHelper
    {
        public static IOrderedQueryable<TModel> OrderBy<TModel>(this IQueryable<TModel> q, string name, string orderType)
        {
            Type entityType = typeof(TModel);
            PropertyInfo p = entityType.GetProperty(name);
            MethodInfo m = typeof(QueryableHelper).GetMethod(orderType).MakeGenericMethod(entityType, p.PropertyType);
            return (IOrderedQueryable<TModel>)m.Invoke(null, new object[] { q, p });
        }

        public static IOrderedQueryable<TModel> OrderByPropertyDescending<TModel, TRet>(IQueryable<TModel> q, PropertyInfo p)
        {
            var expression = GetExpression<TModel, TRet>(q, p);
            return q.OrderByDescending(expression);
        }

        public static IOrderedQueryable<TModel> OrderByProperty<TModel, TRet>(IQueryable<TModel> q, PropertyInfo p)
        {
            var expression = GetExpression<TModel, TRet>(q, p);
            return q.OrderBy(expression);
        }

        private static Expression<Func<TModel, TRet>> GetExpression<TModel, TRet>(IQueryable<TModel> q, PropertyInfo p)
        {
            ParameterExpression pe = Expression.Parameter(typeof(TModel));
            Expression se = Expression.Convert(Expression.Property(pe, p), typeof(TRet));
            var expression = Expression.Lambda<Func<TModel, TRet>>(se, pe);
            return expression;
        }
    }    

我已经删除了一些重复的内容,但还有更多内容可以删除。

我想直接调用这个函数:

OrderByPropertyDescending

目前正在通过这条线调用:

MethodInfo m = typeof(QueryableHelper).GetMethod(orderType).MakeGenericMethod(entityType, p.PropertyType);

有没有办法直接调用这个函数,例如:

var res = OrderByPropertyDescending<TModel, TRet>(q, p);

我的问题是我不知道要为 TRet

传递什么

有什么想法吗?

您可以使用 Expression<Func<TModel, TProperty>> 作为 property 的类型,而不是 PropertyInfo

这将导致像这样的调用:OrderByPropertyDescending(model, model => model.X),其中所有通用参数都会自动计算出来。

然后,您需要从给定表达式中获取 PropertyInfo,因此您只需要检查给定表达式的类型。

我在 Caliburn.Micro 中看到过这样的想法 - 例如,请参阅他们的 ExpressionExtensionshttps://github.com/Caliburn-Micro/Caliburn.Micro/blob/master/src/Caliburn.Micro.Core/ExpressionExtensions.cs

实际上,他们的 GetMemberInfo 适合您。