QueryOver - 确保只添加一次联接表

时间:2016-03-09 15:09:23

标签: c# nhibernate

我有一个相当复杂的用例,需要在代码的各个部分有条件地执行相同的SQL任务。我想复制尽可能少的代码,所以我构建了一些静态帮助器方法,允许我在需要时添加一些JOIN语句。

我知道这可能已经用扩展程序做得更干净了,但是现在我的代码看起来像这样:

static class Foo
{
    // Actually adds some filters which need additional JOINs
    public static IQueryOver<Transaction, Transaction> FromRetailer(Retailer retailer, IQueryOver<Transaction, Transaction> baseQuery = null)
    {
        RetailLocation retailLocation = null;

        return ForRetailerBase(baseQuery)
            .Where(t => retailLocation.Retailer == retailer);
    }

    // Auxiliary method which only adds some JOINs needed in various places
    public static IQueryOver<Transaction, Transaction> ForRetailerBase(IQueryOver<Transaction, Transaction> baseQuery = null)
    {
        if (baseQuery == null)
            baseQuery = QueryOver(); // Custom method that creates a vanilla IQueryOver instance

        // Add all sorts of JOINs needed to query the retailer
        return baseQuery
            .JoinAlias(...)
            .Left.JoinAlias(...)
            // and so on
        ;
    }
}

在商业逻辑中,我要么实际需要按零售商进行过滤(在这种情况下,我会调用FromRetailer(),我会调用ForRetailerBase()),或者我不需要过滤零售商 - 但我仍然需要ForRetailerBase()之后添加的JOIN进行分组。无条件调用ForRetailerBase()显然会在调用FromRetailer()时破坏事物。

我目前正以非常笨拙的方式解决这个问题,通过在业务逻辑中使用布尔值来有条件地执行ForRetailerBase(),只有在FromRetailer()未执行时才会执行。

我意识到这可以在两个级别上修复:要么完全使用更合适的模式,要么通过查询ForRetailerBase()对象来有条件地在baseQuery中添加这些JOIN,以确定它是否已经具有必要性连接。我宁愿选择第一种方法,如果有一种方法(这部分代码仍然相对年轻,我可以轻松地重构它) - 但我也会选择第二种方法。问题是,我不知道如何向任何一个方向前进。

我也意识到,表面上的解决方案是从方法ForRetailerBase()中移除对FromRetailer()的调用,并从业务逻辑中无条件地调用它,但这与我当前的解决方案一样糟糕,因为它需要我的业务逻辑来了解这些方法如何在内部工作。

1 个答案:

答案 0 :(得分:1)

MenuItem nextItem = myMenu.findItem(R.id.loginim); View nextItemView = findViewById(nextItem.getItemId()); nextItemView.setVisibility(View.VISIBLE); ForRetailerBase看起来像是业务逻辑根本不应该知道的东西。它看起来像查询助手,应该由查询存储库处理。

此类存储库将公开业务的查询方法,这些方法将根据需要在内部调用FromRetailerForRetailerBase

这样,您的企业就不需要了解如何构建查询,并且您的查询逻辑仍将在存储库中进行分解。

旁注:您的问题并不真正与您使用的特定技术相关。它在我看来更像是一个代码设计问题。也许你应该在https://softwareengineering.stackexchange.com/上提出这个问题,这是针对这些问题的(见on topic page)。