Lind.DDD.ExpressionExtensions動態(tai)構建(jian)表達(da)式樹,實現對數據(ju)集的權限控(kong)制(zhi)
Lind.DDD框架里提出了(le)對數據集(ji)的(de)(de)控(kong)制(zhi),某些權限的(de)(de)用戶為(wei)某些表添(tian)加某些數據集(ji)的(de)(de)權限,具體(ti)實(shi)現是在一張表中存儲用戶ID,表名(ming),檢索字段,檢索值和檢索操(cao)作(zuo)符(fu),然(ran)后(hou)用戶登陸后(hou),通過自己權限來構建對應表的(de)(de)查(cha)詢語句(ju),即動態構建表達式樹,這種操(cao)作(zuo)一些被寫在業(ye)務(wu)層上,我們可以在業(ye)務(wu)層需(xu)要進行數據集(ji)權限控(kong)制(zhi)的(de)(de)地方,添(tian)加這種策略,下面(mian)具體(ti)分析說明(ming)一下.
看一下數(shu)據集(ji)權限表結(jie)果
public class User_DataSet_Policies { /// <summary> /// 用戶ID /// </summary> public int UserId { get; set; } /// <summary> /// 表名(ming) /// </summary> public string TableName { get; set; } /// <summary> /// 策略(lve)所需字(zi)段 /// </summary> public string PolicyField { get; set; } /// <summary> /// 策略所(suo)需要(yao)值(zhi) /// </summary> public string PolicyValue { get; set; } /// <summary> /// 策略操(cao)作符(fu) /// </summary> public string PolicyOperation { get; set; } }
看一下,在程(cheng)序(xu)中如何動態構建和(he)使用我們的表達式樹(shu)
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); });
下面(mian)貢獻一(yi)下GenerateExpression泛型(xing)方法的(de)原碼(ma),大家可以把它添(tian)加(jia)到我們的(de)LinqExtensions模塊里(li)
/// <summary> /// 表(biao)達式樹的擴展 /// </summary> public class ExpressionExtensions { /// <summary> /// 構建表達式(shi)樹 /// 調用:GenerateExpression(new string[]{"username"},new object[]{"zzl"},new string[]{"="}); /// </summary> /// <typeparam name="T">表類(lei)型(xing)</typeparam> /// <param name="keys">字(zi)段名</param> /// <param name="values">字(zi)段值</param> /// <param name="operation">操作(zuo)符(fu)</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("無效的操作(zuo)符,目前(qian)只(zhi)支持=,%,>,<,>=,<=,in"); } } return (Expression<Func<T, bool>>)Expression.Lambda<Func<T, bool>>(expression_return, new ParameterExpression[] { expression_param }); } }
對于動態構建表達(da)式的介紹就(jiu)到這里了,以后在使(shi)用(yong)過程中如(ru)果出現什么問題(ti),請直接回復我.