C# 使用ORM时的命令/查询分离

C# 使用ORM时的命令/查询分离,c#,asp.net-mvc,nhibernate,command-query-separation,C#,Asp.net Mvc,Nhibernate,Command Query Separation,在我的各种项目中,我实现了命令/查询分离模式,并使用NHibernate作为我的ORM 通常,我将命令和查询保存在与特定活动集(如UserManagement、TagManagement、QuestionManagement等)相关的单独项目中 我非常喜欢将所有内容很好地划分到这些具有易于查找功能的存储库中。这样做肯定有好处 然而,我开始怀疑这种抽象对于基本查询的价值,特别是考虑到NHibernate本身已经提供了如此强大的抽象 在我的MVC控制器中考虑这一点: _nHibernateSessi

在我的各种项目中,我实现了命令/查询分离模式,并使用NHibernate作为我的ORM

通常,我将命令和查询保存在与特定活动集(如UserManagement、TagManagement、QuestionManagement等)相关的单独项目中

我非常喜欢将所有内容很好地划分到这些具有易于查找功能的存储库中。这样做肯定有好处

然而,我开始怀疑这种抽象对于基本查询的价值,特别是考虑到NHibernate本身已经提供了如此强大的抽象

在我的MVC控制器中考虑这一点:

_nHibernateSession.Get<UserProfile>(_sessionData.UserId);
我可以将其抽象为UserManagement存储库中的查询,但我不确定它提供了什么价值


你觉得怎么样?您是将所有内容都保留在命令/查询范例中,还是直接在控制器中使用nhibernate会话来处理这样的简单请求?

我更喜欢将所有查询保留在存储库中,如果需要进行大量不同的查询,可以将实现IQueryable和wrap session.query的LINQ的存储库公开给Nhibernate,这对HQL或条件有限制

但对我来说,没有一个合理的理由这样做,只有当您向其他人提供数据访问层时,您才会知道查询


您可以在我正在使用的DDD上看到这样一个例子。

我更喜欢将所有查询保留在存储库中,如果您需要进行许多不同的查询,您可以公开实现IQueryable和wrap会话的存储库。LINQ到Nhibernate的查询,这对HQL或条件有限制

但对我来说,没有一个合理的理由这样做,只有当您向其他人提供数据访问层时,您才会知道查询


您可以在我正在使用的DDD上看到这样一个例子。

我强烈建议您在MVC控制器和NHibernate之间保持一定的抽象级别,特别是当您需要对MVC控制器进行单元测试时。没有存储库层,创建需要模拟存储库层的单元测试要困难得多。

我强烈建议您在MVC控制器和NHibernate之间保持一定的抽象级别,特别是当您需要对MVC控制器进行单元测试时。没有存储库层,创建需要模拟存储库层的单元测试要困难得多。

通常我不使用存储库,因为我认为它们在我的代码中添加了太多的抽象。我更喜欢直接在服务/控制器层构建的视图模型。如果我想编写一个单元测试,我可以针对服务或控制器编写它。如果要重用某些查询条件,只需编写扩展方法:

    public static IQueryable<User> Administrators(this IQueryable<User> users)
    {
        return users.Where(x => x.Role.Id == Role.Const.Admin);
    }
关于这一点,我推荐以下文章:
通常我不使用存储库,因为我认为它们在我的代码中添加了太多的抽象。我更喜欢直接在服务/控制器层构建的视图模型。如果我想编写一个单元测试,我可以针对服务或控制器编写它。如果要重用某些查询条件,只需编写扩展方法:

    public static IQueryable<User> Administrators(this IQueryable<User> users)
    {
        return users.Where(x => x.Role.Id == Role.Const.Admin);
    }
关于这一点,我推荐以下文章: