Lind.DDD.ExpressionExtensions动态构建表达式树,实现对数据集的权限控制
Lind.DDD框架里提出了对数据集的控制,某些权限的用户为某些表添加某些数据集的权限,具体实现是在一张表中存储用户ID,表名,检索字段,检索值和检索操作符,然后用户登陆后,通过自己权限来构建对应表的查询语句,即动态构建表达式树,这种操作一些被写在业务层上,我们可以在业务层需要进行数据集权限控制的地方,添加这种策略,下面具体分析说明一下.
看一下数据集权限表结果
public class User_DataSet_Policies { /// <summary> /// 用户ID /// </summary> public int UserId { get; set; } /// <summary> /// 表名 /// </summary> public string TableName { get; set; } /// <summary> /// 策略所需字段 /// </summary> public string PolicyField { get; set; } /// <summary> /// 策略所需要值 /// </summary> public string PolicyValue { get; set; } /// <summary> /// 策略操作符 /// </summary> public string PolicyOperation { get; set; } }
看一下,在程序中如何动态构建和使用我们的表达式树
Expression<Func<User, bool>> exe = ExpressionExtensions.GenerateExpression<User>( new string[] { "Age", "UserName" }, new object[] { "12", "zzl" }, new string[] { "=", "=" }); userList.Where(exe.Compile()).ToList().ForEach(i => { Console.WriteLine(i.UserName); });
下面贡献一下GenerateExpression泛型方法的原码,大家可以把它添加到我们的LinqExtensions模块里
/// <summary> /// 表达式树的扩展 /// </summary> public class ExpressionExtensions { /// <summary> /// 构建表达式树 /// 调用:GenerateExpression(new string[]{"username"},new object[]{"zzl"},new string[]{"="}); /// </summary> /// <typeparam name="T">表类型</typeparam> /// <param name="keys">字段名</param> /// <param name="values">字段值</param> /// <param name="operation">操作符</param> /// <returns></returns> public static Expression<Func<T, bool>> GenerateExpression<T>(string[] keys, object[] values, string[] operation) { var TType = typeof(T); Expression expression_return = Expression.Constant(true); ParameterExpression expression_param = Expression.Parameter(TType, "p"); Expression expression; for (int i = 0; i < keys.Length; i++) { switch (operation[i]) { case "=": expression = Expression.Equal(Expression.Call(Expression.Property(expression_param, TType.GetProperty(keys[i])), TType.GetMethod("ToString")), Expression.Constant(values[i])); expression_return = Expression.And(expression_return, expression); break; case "%": expression = Expression.Call(Expression.Property(expression_param, TType.GetProperty(keys[i])), typeof(string).GetMethod("Contains"), Expression.Constant(values[i], typeof(string))); expression_return = Expression.And(expression_return, expression); break; case ">": expression = Expression.Call(Expression.Property(expression_param, TType.GetProperty(keys[i])), typeof(double).GetType().GetMethod("GreaterThan"), Expression.Constant(values[i])); expression_return = Expression.And(expression_return, expression); break; case "<": expression = Expression.Call(Expression.Property(expression_param, TType.GetProperty(keys[i])), typeof(double).GetType().GetMethod("LessThan"), Expression.Constant(values[i])); expression_return = Expression.And(expression_return, expression); break; case ">=": expression = Expression.Call(Expression.Property(expression_param, TType.GetProperty(keys[i])), typeof(double).GetType().GetMethod("GreaterThanOrEqual"), Expression.Constant(values[i])); expression_return = Expression.And(expression_return, expression); break; case "<=": expression = Expression.Call(Expression.Property(expression_param, TType.GetProperty(keys[i])), TType.GetProperty(keys[i]).GetType().GetMethod("LessThanOrEqual"), Expression.Constant(values[i])); expression_return = Expression.And(expression_return, expression); break; case "in": string[] strarr = values[i].ToString().Split(','); Expression or_return = Expression.Constant(false); for (int k = 0; k < strarr.Length; k++) { expression = Expression.Equal(Expression.Call(Expression.Property(expression_param, TType.GetProperty(keys[i])), TType.GetMethod("ToString")), Expression.Constant(strarr[k])); or_return = Expression.Or(or_return, expression); } expression_return = Expression.And(expression_return, or_return); break; default: throw new ArgumentException("无效的操作符,目前只支持=,%,>,<,>=,<=,in"); } } return (Expression<Func<T, bool>>)Expression.Lambda<Func<T, bool>>(expression_return, new ParameterExpression[] { expression_param }); } }
对于动态构建表达式的介绍就到这里了,以后在使用过程中如果出现什么问题,请直接回复我.
分类:
其它 / 系统架构
【推荐】AI 的力量,开发者的翅膀:欢迎使用 AI 原生开发工具 TRAE
【推荐】2025 HarmonyOS 鸿蒙创新赛正式启动,百万大奖等你挑战
【推荐】博客园的心动:当一群程序员决定开源共建一个真诚相亲平台
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何正确实现一个 BackgroundService
· 抽象与性能:从 LINQ 看现代 .NET 的优化之道
· AI 时代,为什么我们还有必要写博客?
· 行业思考:不是前端不行,是只会前端不行
· C#高级GDI+实战:从零开发一个流程图
· 记一次酣畅淋漓的js逆向
· 被 DDoS 攻击的一夜
· 一个被BCL遗忘的高性能集合:C# CircularBuffer<T>深度解析
· 如何正确实现一个 BackgroundService
· 上周热点回顾(7.28-8.3)
2014-12-30 知方可补不足~Sqlserver中的几把锁和.net中的事务级别
2012-12-30 vs2012~ 开发人员的福音
2011-12-30 基础才是重中之重~类是怎么执行的