轻量级数据过滤方案

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低效。

原文地址:https://www.cnblogs.com/yuanhuaming/p/1664564.html