zoukankan      html  css  js  c++  java
  • 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 });
            }
        }

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

    回到目录

  • 相关阅读:
    无法执行 FunctionImport“entitys.xx”,因为未将它映射到存储函数。EF
    图解TCP/IP→第2章基础知识
    50个查询系列-第二个查询
    50个查询系列-第一个查询
    50个查询系列-建表和插入数据
    027医疗项目-模块二:药品目录的导入导出-导入功能的Action的编写
    026医疗项目-模块二:药品目录的导入导出-导入功能的Service的编写
    025医疗项目-模块二:药品目录的导入导出-HSSF导入类的封装
    024医疗项目-模块二:药品目录的导入导出-HSSF导入类的学习
    023医疗项目-模块二:药品目录的导入导出-从数据库中查出数据用XSSF导出excel并存放在虚拟目录最后下载(包括调试)
  • 原文地址:https://www.cnblogs.com/lori/p/5087708.html
Copyright © 2011-2022 走看看