4

我正在尝试使用 Fluent NHibernate 和 Linq to NHibernate 设置适当的域架构。我有我的控制器调用我的存储库类,这些类在引擎盖下执行 NHibernate 并传回 ICollections 数据。这似乎运作良好,因为它抽象了数据访问并将 NHibernate 功能保留在“小字”中。

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

所以这是我看到的三个选项:

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

抱歉,如果我没有很好地解释这一点。我刚开始接触 DDD,很多这个术语对我来说仍然是新的。谢谢!

4

4 回答 4

2

正如 lomaxx 指出的那样,您需要 query.Expand。

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

我在我的博客上发布了一些使用 ICriteria API 的示例。ICriteria API 有FetchMode代替Expand,但想法是一样的。

于 2010-05-11T13:59:16.977 回答
1

我尝试将所有查询逻辑保留在我的存储库中,并尝试仅从它们传回 ICollection。

在您的情况下,我会传入一些参数来确定您是否想要预先加载角色并以这种方式构造 IQueryable。例如:

GetAllUsers(bool loadRoles)
{
    var query = session.Linq<Users>();
    if(loadRoles)
       query.Expand("Roles");
    return query.ToList();
}
于 2010-05-11T13:52:48.293 回答
0

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

于 2010-05-11T13:54:17.587 回答
0

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

我会创建一个名为 的单独存储库方法GetRolesForUser(User user),对角色使用延迟加载,或者使用GetAllUsers(bool loadRoles)lomaxx 的回答中提到的方法。

我倾向于延迟加载角色或存储库中的单独方法。

于 2010-05-11T13:58:00.857 回答