让 Linq 支持动态列名排序
/// Queryable的内部实现
/// 做了部分调整
public static IOrderedQueryable<TSource> OrderBy<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
{
if (source == null) throw new Exception("source");
if (keySelector == null) throw new Exception("keySelector");
//使用提供程序的的CreateQuery,来建立表达公树
//建立后的表达式数在调用Provider.Execute时被正式解析成以及执行
return (IOrderedQueryable<TSource>)source.Provider.CreateQuery<TSource>(
Expression.Call(
null,
//下面句返回的OrderBy<TSource,TKey>方法的MethodInfo
((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new Type[] { typeof(TSource), typeof(TKey) }),
//关键是Expression.Quote(keySelector)
//需要使用自己LambdaExpression来替换KeySelector
new Expression[] { source.Expression, Expression.Quote(keySelector) }
)
);
}
/// 由于本质Linq To EF 支持OrderBy 等
/// 所以只要模拟个keySelector后,将剩余的工作交还给Linq To EF Provider来处理
public static IOrderedQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> source, string propertyStr) where TEntity : class
{
//以下四句用来购建立 c=>c.propertyStr 的Expression
ParameterExpression param = Expression.Parameter(typeof(TEntity), "c");
PropertyInfo property = typeof(TEntity).GetProperty(propertyStr);
Expression propertyAccessExpression = Expression.MakeMemberAccess(param, property);
LambdaExpression le = Expression.Lambda(propertyAccessExpression, param);
Type type = typeof(TEntity);
//Expression.Call跟上面的一样,这里采用重载形式,上面的GetCurrentMethod结果也是"OrderBy"
//Expression.Call方法会利用typeof(Queryable),"OrderBy",new Type[]{type,property.PropertyType}三个参数
//合成跟MethodInfo等同的信息
MethodCallExpression resultExp = Expression.Call(typeof(Queryable), "OrderBy", new Type[] { type, property.PropertyType }, source.Expression, Expression.Quote(le));
return (IOrderedQueryable<TEntity>)source.Provider.CreateQuery<TEntity>(resultExp);
}
下面的参考地址中可以找到完整实现
//===================
参考下文:
http://www.cnblogs.com/xxfss2/archive/2010/12/13/1905023.html
http://www.cnblogs.com/Terrylee/archive/2008/08/01/custom-linq-provider-part-1-expression-tree.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述