使用全局查询策略


  全局查询策略是指以外部动态的方式将查询表达式注入到以当前会话隔离的查询中。比如大量的业务表使用了区域编码和年度进行分区,当使用者登录后,需要将使用者所属的区域和当前的年度自动组织到查询中,这样才能达到表分区的理想效果。

  GlobalQueryPolicy 类用于管理每一个使用者将采取什么样的查询策略,Register 方法需要指定一个函数,在 Web 中该函数一般为 HttpContext.Current. Session.SessionID。

/// <summary>
/// 注册查询策略
/// </summary>
/// <param name="regionCode">行政区划编码。</param>
/// <param name="year">当前年度。</param>
public static void Register(string regionCode, int year)
{
    var func = new Func<string>(() => HttpContext.Current.Session.SessionID);

    var session = GlobalQueryPolicy.Create(func);
    if (session.Count > 0)
    {
        return;
    }

    session.Register<BaseAccessory>(s => s.RegionCode == regionCode && s.Year == year);
    session.Register<BaseApply>(s => s.RegionCode == regionCode && s.Year == year);
    session.Register<BaseBook>(s => s.RegionCode == regionCode && s.Year == year);
}

  以上代码将为每个会话(使用者)创建一个查询策略,这样的实际上是比较浪费的。Register 方法可以指定一个标识,使标识的会话使用同一个查询策略。

/// </summary>
/// <param name="regionCode">行政区划编码。</param>
/// <param name="year">当前年度。</param>
public static void Register(string regionCode, int year)
{
    var func = new Func<string>(() => HttpContext.Current.Session.SessionID);

    var session = GlobalQueryPolicy.Create(func, regionCode + year);
    if (session.Count > 0)
    {
        return;
    }

    session.Register<BaseAccessory>(s => s.RegionCode == regionCode && s.Year == year);
    session.Register<BaseApply>(s => s.RegionCode == regionCode && s.Year == year);
    session.Register<BaseBook>(s => s.RegionCode == regionCode && s.Year == year);
}

  这样的话,同一区域同一年度的使用者会共用同一个查询策略。

  注册全局查询策略后,业务层编写的查询语句均无需考虑区域编码和年度的问题。