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 });
        }
    }
复制代码

对于动态构建表达式的介绍就到这里了,以后在使用过程中如果出现什么问题,请直接回复我.

回到目录

posted @   张占岭  阅读(1431)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
历史上的今天:
2014-12-30 知方可补不足~Sqlserver中的几把锁和.net中的事务级别
2012-12-30 vs2012~ 开发人员的福音
2011-12-30 基础才是重中之重~类是怎么执行的
点击右上角即可分享
微信分享提示