【发布时间】:2018-10-23 09:23:10
【问题描述】:
我为 IQueryable OrderBy(以及 OrderByDescending、ThenBy 和 ThenByDescending)编写了一个扩展方法,它们都调用我的函数 CreateExpression 来获取用于排序的表达式。
问题是如果有人使用无效参数调用此方法,例如字符串不是正在排序的对象类型中的成员名称。这就是为什么我检查 pi 是否不为空。现在,如果参数无效且 pi 为 null,我需要返回 null 以外的其他内容,但我不太确定该怎么做。我想返回一个不排序的表达式,这可能吗?我该怎么做?
public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string orderBy)
{
if (!string.IsNullOrWhiteSpace(orderBy))
{
var resultExp = CreateExpression(source, "OrderBy", orderBy);
return source.Provider.CreateQuery<T>(resultExp);
}
else
{
return source;
}
}
private static MethodCallExpression CreateExpression<T>(IQueryable<T> source, string methodName, string orderBy)
{
if (methodName != "OrderBy" && methodName != "OrderByDescending" && methodName != "ThenBy" && methodName != "ThenByDescending")
methodName = "OrderBy";
if (!string.IsNullOrWhiteSpace(orderBy))
{
PropertyInfo pi = typeof(T).GetProperty(orderBy);
if (pi != null)
{
var parameter = Expression.Parameter(typeof(T), "p");
MemberExpression me = Expression.MakeMemberAccess(parameter, pi);
var orderByExp = Expression.Lambda(me, parameter);
return Expression.Call(typeof(Queryable), methodName,
new Type[] { typeof(T), pi.PropertyType }, source.Expression, Expression.Quote(orderByExp));
}
}
//todo
return null;
}
【问题讨论】:
-
谢谢 CodingYoshi 和 Simon Katanski,你们的回复都非常好。我最终抛出了一个异常,因为我无法影响将字符串参数更改为表达式。我希望我可以标记两个答案,但我会标记 Simons 的答案,因为如果我可以摆脱字符串参数,我会这样做。但是,我认为我不需要首先编写扩展方法,我可以直接使用 OrderBy 的默认实现。谢谢!
-
你仍然可以使用你的扩展方法: private static MethodCallExpression CreateExpression
(IQueryable source, string methodName, string orderBy) 你可以使用一个表达式来代替orderBy——只是一个小的优化.
标签: c#