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 });
            }
        }

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

    回到目录

  • 相关阅读:
    【Educational Codeforces Round 101 (Rated for Div. 2) C】Building a Fence
    【Codeforces Round #698 (Div. 2) C】Nezzar and Symmetric Array
    【Codeforces Round #696 (Div. 2) D】Cleaning
    【Codeforces Round #696 (Div. 2) C】Array Destruction
    【Educational Codeforces Round 102 D】Program
    【Educational Codeforces Round 102 C】No More Inversions
    【Good Bye 2020 G】Song of the Sirens
    【Good Bye 2020 F】Euclid's nightmare
    使用mobx入门
    requestAnimationFrame 控制速度模拟setinterval
  • 原文地址:https://www.cnblogs.com/lori/p/5087708.html
Copyright © 2011-2022 走看看