你的位置:首页 > ASP.net教程

[ASP.net教程]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 });    }  }

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

回到目录