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