我正在尝试使用Fluent NHibernate和Linq到NHibernate建立适当的域架构。我让我的控制器调用我的Repository类,它们在引擎盖下执行NHibernate并传回ICollections数据。这似乎很有效,因为它抽象了数据访问并将NHibernate功能保持在“精细打印”中。
但是,现在我发现我的控制器需要在不同的上下文中使用相同的数据调用。例如,我的repo返回一个Users列表。当我想显示用户列表时,这很好,但是当我想开始利用子类来显示角色等时,我遇到了SELECT N + 1问题。我知道如何在NHibernate中更改它,所以它使用连接,但我的具体问题是我在哪里放这个逻辑?我不希望每个GetAllUsers()调用也返回角色,但我确实想要其中的一些。
所以这是我看到的三个选项:
很抱歉,如果我没有解释清楚这一点。我刚刚进入DDD,很多这个术语对我来说还是新的。谢谢!
答案 0 :(得分:2)
正如lomaxx指出的那样,你需要query.Expand。
为了防止您的存储库因各种可能情况的各种方法而变得模糊,您可以创建查询对象来进行可配置的查询。
我使用ICriteria API on my blog发布了一些示例。 ICriteria API有FetchMode
而不是Expand
,但想法是一样的。
答案 1 :(得分:1)
我尝试将所有查询逻辑保存在我的存储库中,并尝试仅从它们传回ICollection。
在你的情况下,我会传递一些参数来确定你是否想要加载角色,并以这种方式构建IQueryable。例如:
GetAllUsers(bool loadRoles)
{
var query = session.Linq<Users>();
if(loadRoles)
query.Expand("Roles");
return query.ToList();
}
答案 2 :(得分:0)
我会选择2,创建两个存储库。也许我会考虑为GetRoleByUser(用户用户)创建另一个存储库调用。因此,如果需要,您可以在单独的线程上更改用户选择时访问用户的角色,这样会增加您的性能,并且不会为每个用户加载每个用户的角色,这将需要大多数资源。
答案 3 :(得分:0)
听起来你问是否有可能使GetAllUsers()
有时只返回用户实体,有时会返回用户和角色。
我要么创建一个名为GetRolesForUser(User user)
的单独存储库方法,对Roles使用延迟加载,或者使用lomaxx答案中提到的GetAllUsers(bool loadRoles)
。
我会倾向于在您的存储库中使用延迟加载角色或单独的方法。