热门:网页模板.net视频教程JQueryMVCjsonExtJs源码示例三级联动JQuery菜单
您现在的位置:.Net中文社区>> .Net编程>>正文内容

轻量级数据过滤方案

发布时间:2010年02月06日点击数: 佚名

1 基于ADO.NET

这是一个权限到数据的简单实现。关于表的设计就不讨论了,网上很多。

需求是这样的我们需要一个数据过滤方案。比如订单,(A权限)只能看到自己处理的订单,(B权限可以看到所有的订单)。那么这个A权限对于B权限来说就是改变一下条件。那么怎样处理才能达到一个期待的效果呢?实现方法如下:

RolesExtensions.class 专门用来做权限过滤的类

  1. public static class RolesExtensions  
  2. {  
  3.     /// <summary>  
  4.     ///  过滤不需要的订单  
  5.     /// </summary>  
  6.     /// <param name="query"></param>  
  7.     /// <param name="alias">存放Key=表名;value=表别名的字典</param>  
  8.     /// <returns></returns>  
  9.     public static StringBuilder WithFilterOrders(this StringBuilder query, StringDictionary alias)  
  10.     {  
  11.         string userIdInSession = "YHM";  
  12.         if (alias == null)  
  13.         {  
  14.             // 默认表名=表别名,表名直接用使用字符串  
  15.             return query.Col("TFJ006""RECEIVER").Eq(userIdInSession)  
  16.                                     .And().Col("TFJ006""DEL_KEY").Eq("N");  
  17.         }  
  18.         else  
  19.         {  
  20.             return query.Col(alias["TFJ006"], "RECEIVER").Eq(userIdInSession)  
  21.                         .And().Col(alias["TFJ007"], "DEL").Eq("N");  
  22.         }  
  23.     } 

辅助类。理解就行

我本来想通过继承StringBuilder来处理Restrictions里的操作的,没想到StringBuilder无法继承。类名我都想好了SqlBuilder,多好的名字。

  1. public struct SimpleExpression  
  2. {  
  3.     public static string Eq = " = ";  
  4.     public static string Not = " ! ";  
  5.     public static string Lt = " < ";  
  6.     public static string Gt = " > ";  
  7.     public static string Like = " like ";  
  8.     public static string Ge = " >= ";  
  9.     public static string Le = " <= ";  
  10.    
  11.     public static string And = " And ";  
  12.     public static string Or = " Or ";  
  13. }  
  14.    
  15. public static class Restrictions  
  16. {  
  17.     public static StringBuilder Col(this StringBuilder sb, string alias, string columnName)  
  18.     {  
  19.         return sb.Append(alias + "." + columnName);  
  20.     }  
  21.    
  22.     public static StringBuilder Eq<T>(this StringBuilder sb, T value )  
  23.     {  
  24.         string perfix = "";  
  25.         if (!(value is  int))  
  26.         {  
  27.             perfix = "'";  
  28.         }  
  29.         return sb.Append(SimpleExpression.Eq).Append(perfix + value + perfix);  
  30.     }  
  31.    
  32.    
  33.     public static StringBuilder Like(this StringBuilder sb, string value)  
  34.     {  
  35.         return sb.Append(SimpleExpression.Like).Append(value);  
  36.     }  
  37.    
  38.     public static StringBuilder And(this StringBuilder sb )  
  39.     {  
  40.         return sb.Append(SimpleExpression.And);  
  41.     }  
  42.    
  43.     public static StringBuilder Or(this StringBuilder sb)  
  44.     {  
  45.         return sb.Append(SimpleExpression.Or);  
  46.     }  

那么在实现的时候可以直接在原有的sql文下面直接这样写了。 sql.WithFilterOrders();

当然这样方式会随着sql的复杂度无法适应。我觉得复杂sql应该优先使用视图或者存储过程。


2 基于Linq to Sql

利用linq的延迟加载能够很方便的解决数据过滤的问题。会LINQ的一看就懂

  1. public static class LinqRolesExtensions  
  2. {  
  3.     public static IQueryable<City> WithFilterCities(this IQueryable<City> query)  
  4.     {  
  5.        return query.Where(a => a.CITYCD != "SH");  
  6.     }  
  7.    
  8.     public static IQueryable<FIT_Order> WithFilterOrders(this IQueryable<FIT_Order> query)  
  9.     {  
  10.         string userIdInSession = "YHM";  
  11.         return query.Where(a => a.CreatedBy == userIdInSession  && a.FIT_OrderHotel.Count > 0 );  
  12.     }  
  13.     // public static   
  14.    

调用方法:

  1. public List<CityInfo> GetCitys()  
  2. {  
  3.     return GetAll().Where(a=>a.IS_DELETE == 0).WithFilterCities()  
  4.         .OrderBy(a=>a.CITYNM ).Select(  
  5.        a=> new CityInfo() {   
  6.         CITYCD =  a.CITYCD,  
  7.         CITYNM = a.CITYNM  
  8.         }  
  9.         ).ToList();  

虽然这种方法非常方便,可能会造成生成的sql低效。

在灵活性上不如AOP好,不过我最近在想如何AopExtenisons.不是要实现aop,而是实现aop的功能。大致写法如下:

  1. this.MethodBefore().XXXX().MethodAfter(); 

我可以通过获取this的type和session中的内容来相关的操作。

本站热点业务

更多模板/案例展示

关于我们 | 联系我们 | 团队日志 | 网站地图 | 网站合作