直接调用方法——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
中看到过这样的想法 - 例如,请参阅他们的 ExpressionExtensions
:https://github.com/Caliburn-Micro/Caliburn.Micro/blob/master/src/Caliburn.Micro.Core/ExpressionExtensions.cs
实际上,他们的 GetMemberInfo
适合您。
我用这个答案写了下面的代码: 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
中看到过这样的想法 - 例如,请参阅他们的 ExpressionExtensions
:https://github.com/Caliburn-Micro/Caliburn.Micro/blob/master/src/Caliburn.Micro.Core/ExpressionExtensions.cs
实际上,他们的 GetMemberInfo
适合您。