1 基于ADO.NET
这是一个权限到数据的简单实现。关于表的设计就不讨论了,网上很多。
需求是这样的我们需要一个数据过滤方案。比如订单,(A权限)只能看到自己处理的订单,(B权限可以看到所有的订单)。那么这个A权限对于B权限来说就是改变一下条件。那么怎样处理才能达到一个期待的效果呢?实现方法如下:
RolesExtensions.class 专门用来做权限过滤的类
- public static class RolesExtensions
- {
- /// <summary>
- /// 过滤不需要的订单
- /// </summary>
- /// <param name="query"></param>
- /// <param name="alias">存放Key=表名;value=表别名的字典</param>
- /// <returns></returns>
- public static StringBuilder WithFilterOrders(this StringBuilder query, StringDictionary alias)
- {
- string userIdInSession = "YHM";
- if (alias == null)
- {
- // 默认表名=表别名,表名直接用使用字符串
- return query.Col("TFJ006", "RECEIVER").Eq(userIdInSession)
- .And().Col("TFJ006", "DEL_KEY").Eq("N");
- }
- else
- {
- return query.Col(alias["TFJ006"], "RECEIVER").Eq(userIdInSession)
- .And().Col(alias["TFJ007"], "DEL").Eq("N");
- }
- }
辅助类。理解就行
我本来想通过继承StringBuilder来处理Restrictions里的操作的,没想到StringBuilder无法继承。类名我都想好了SqlBuilder,多好的名字。
- public struct SimpleExpression
- {
- public static string Eq = " = ";
- public static string Not = " ! ";
- public static string Lt = " < ";
- public static string Gt = " > ";
- public static string Like = " like ";
- public static string Ge = " >= ";
- public static string Le = " <= ";
- public static string And = " And ";
- public static string Or = " Or ";
- }
- public static class Restrictions
- {
- public static StringBuilder Col(this StringBuilder sb, string alias, string columnName)
- {
- return sb.Append(alias + "." + columnName);
- }
- public static StringBuilder Eq<T>(this StringBuilder sb, T value )
- {
- string perfix = "";
- if (!(value is int))
- {
- perfix = "'";
- }
- return sb.Append(SimpleExpression.Eq).Append(perfix + value + perfix);
- }
- public static StringBuilder Like(this StringBuilder sb, string value)
- {
- return sb.Append(SimpleExpression.Like).Append(value);
- }
- public static StringBuilder And(this StringBuilder sb )
- {
- return sb.Append(SimpleExpression.And);
- }
- public static StringBuilder Or(this StringBuilder sb)
- {
- return sb.Append(SimpleExpression.Or);
- }
- }
那么在实现的时候可以直接在原有的sql文下面直接这样写了。 sql.WithFilterOrders();
当然这样方式会随着sql的复杂度无法适应。我觉得复杂sql应该优先使用视图或者存储过程。
2 基于Linq to Sql
利用linq的延迟加载能够很方便的解决数据过滤的问题。会LINQ的一看就懂
- public static class LinqRolesExtensions
- {
- public static IQueryable<City> WithFilterCities(this IQueryable<City> query)
- {
- return query.Where(a => a.CITYCD != "SH");
- }
- public static IQueryable<FIT_Order> WithFilterOrders(this IQueryable<FIT_Order> query)
- {
- string userIdInSession = "YHM";
- return query.Where(a => a.CreatedBy == userIdInSession && a.FIT_OrderHotel.Count > 0 );
- }
- // public static
- }
调用方法:
- public List<CityInfo> GetCitys()
- {
- return GetAll().Where(a=>a.IS_DELETE == 0).WithFilterCities()
- .OrderBy(a=>a.CITYNM ).Select(
- a=> new CityInfo() {
- CITYCD = a.CITYCD,
- CITYNM = a.CITYNM
- }
- ).ToList();
- }
虽然这种方法非常方便,可能会造成生成的sql低效。
在灵活性上不如AOP好,不过我最近在想如何AopExtenisons.不是要实现aop,而是实现aop的功能。大致写法如下:
- this.MethodBefore().XXXX().MethodAfter();
我可以通过获取this的type和session中的内容来相关的操作。