代码之家  ›  专栏  ›  技术社区  ›  Mike Cole

在哪里放置nhibernate查询逻辑?

  •  4
  • Mike Cole  · 技术社区  · 16 年前

    我正在尝试使用fluent nhibernate和linq to nhibernate建立适当的域体系结构。我让我的控制器调用我的存储库类,这些类在引擎盖下执行nhibernate thang,并返回数据的ICollections。这似乎工作得很好,因为它抽象了数据访问,并将nhibernate功能保留在“精细打印”中。

    但是,现在我发现控制器需要在不同的上下文中使用相同的数据调用。例如,我的repo返回用户列表。当我想显示一个用户列表时,这很好,但是当我想开始利用子类来显示角色等时,我遇到了select n+1问题。我知道如何在nhibernate中更改它,所以它使用连接,但我的具体问题是,我应该把这个逻辑放在哪里?我不希望每个getAllUsers()调用也返回角色,但我希望其中一些角色返回。

    下面是我看到的三个选项:

    1. 更改我的映射中的设置,以便将角色加入到我的查询中。
    2. 创建两个存储库调用-getAllUsers()和getUserSandroles()。
    3. 将我的IQueryable对象从存储库返回到控制器,并使用nhibernate扩展方法。

    对不起,如果我解释得不好。我刚开始学DDD,很多这个术语对我来说还是新的。谢谢!

    4 回复  |  直到 16 年前
        1
  •  2
  •   Jan Willem B    16 年前

    正如lomaxx指出的,您需要query.expand。

    为了防止您的存储库在各种可能的情况下被各种方法所掩盖,您可以创建查询对象来进行可配置的查询。

    我发布了一些使用icriteria API的示例 on my blog . ICriteria API具有 FetchMode 而不是 Expand 但想法是一样的。

        2
  •  1
  •   lomaxx    16 年前

    我尝试将所有查询逻辑保存在我的存储库中,并尝试只从中传递ICollection。

    在您的情况下,我将传递一些参数来确定您是否希望加载角色,并以这种方式构造IQueryable。例如:

    GetAllUsers(bool loadRoles)
    {
        var query = session.Linq<Users>();
        if(loadRoles)
           query.Expand("Roles");
        return query.ToList();
    }
    
        3
  •  0
  •   Will Marcouiller    16 年前

    我会选择2,创建两个存储库。也许我会考虑创建另一个对getrolebyuser(用户用户)的存储库调用。因此,如果需要,您可以在单独线程上的用户选择更改时访问用户的角色,这样它将提高您的性能,并且不会为每个用户加载每个用户的角色,这将需要大多数资源。

        4
  •  0
  •   Adam    16 年前

    听起来你在问是否有可能 GetAllUsers() 有时只返回用户实体,有时返回用户和角色。

    我可以创建一个单独的存储库方法 GetRolesForUser(User user) ,对角色使用延迟加载,或使用 GetAllUsers(bool loadRoles) 罗马克斯的回答提到。

    我倾向于使用懒惰的加载角色或存储库中的单独方法。