回到目錄Lind.DDD框架里提出了對數據集的控制,某些許可權的用戶為某些表添加某些數據集的許可權,具體實現是在一張表中存儲用戶ID,表名,檢索欄位,檢索值和檢索操作符,然後用戶登陸後,通過自己許可權來構建對應表的查詢語句,即動態構建表達式樹,這種操作一些被寫在業務層上,我們可以在業務層需要進行數據集許可權...
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 }); } }
對於動態構建表達式的介紹就到這裡了,以後在使用過程中如果出現什麼問題,請直接回覆我.