Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Nhibernate 在使用ORM时,如何实现命令查询分离(CQS)?_Nhibernate_Orm_Cqrs - Fatal编程技术网

Nhibernate 在使用ORM时,如何实现命令查询分离(CQS)?

Nhibernate 在使用ORM时,如何实现命令查询分离(CQS)?,nhibernate,orm,cqrs,Nhibernate,Orm,Cqrs,CQS体系结构模式背后的原则是将查询和命令分离到不同的路径中。理想情况下,持久性存储可以进行读/写分区,但在我的例子中,只有一个规范化的数据库 如果您使用的是ORM(在我的例子中是NHibernate),那么很明显,在发出命令时会使用ORM。但是,对于所有需要运行以形成用户屏幕数据(DTO)的各种查询,在执行CQS的查询端时,是否通常会放弃ORM 我应该在哪里实现查询和DTO预测?纯ADO.NET(数据读取器、DTO、数据表、存储过程)?有些查询是非常独特的,需要大量的连接才能将所有内容组合在一

CQS体系结构模式背后的原则是将查询和命令分离到不同的路径中。理想情况下,持久性存储可以进行读/写分区,但在我的例子中,只有一个规范化的数据库

如果您使用的是ORM(在我的例子中是NHibernate),那么很明显,在发出命令时会使用ORM。但是,对于所有需要运行以形成用户屏幕数据(DTO)的各种查询,在执行CQS的查询端时,是否通常会放弃ORM


我应该在哪里实现查询和DTO预测?纯ADO.NET(数据读取器、DTO、数据表、存储过程)?有些查询是非常独特的,需要大量的连接才能将所有内容组合在一起。我不想为查询对数据库进行非规范化,但我可以创建视图(穷人的非规范化)。

无需使用不同的方法来读取数据库和更新数据库。CQS只是声明更新数据存储的命令应该与从数据存储读取状态的查询分开

您仍然可以使用NHibernate从数据存储中读取数据,但您可能希望通过创建两个不同的类来封装数据访问,从而使其变得明显。一个类将具有读取(查询)数据存储的方法,另一个类将具有向数据存储发出命令(添加、更新、删除)的方法


您试图避免的是一种方法,该方法从数据库中获取消息,然后将该消息标记为已在数据库中读取。这应该是两个不同的方法调用。您不应该更改状态并从相同的方法返回值。

我假设CQS指的是DDD架构模式aka,而不是严格意义上的传统原则

我仍然会使用NHibernate作为您的只读模型。它有许多优点,例如未来查询和多查询、延迟/急切加载等。。。这将优化数据库聊天。此外,如果UI允许用户实质性地更改where子句,则使用ORM组合查询将更容易

关于如何从技术上处理只读模型,可以使用NHibernate标记实体。您可以简单地将所有读取模型实体标记为不可变。此外,我不认为您可以更新NHibernate中的投影,因此这是作为只读模型的另一个选择(如果我错了,请有人纠正我,因为我不是100%确定)


关于丑陋或不可能的NH映射:NH可以映射到视图和存储过程,所以我认为在需要时使用这些映射是很好的。对于只读场景,视图可能比存储过程更灵活,因为SQL仍然是动态的。但是,如果您需要对这些扁平结构中的任何一个进行读/写,我会映射到存储过程

命令部分使用EF,查询链使用stright ADO.NET=>dto。优点:

1) 能够优化SQL查询并使用未抽象到ORM层的高级数据库存储功能

2) 减少开销


但是,我们只对需要的部分(搜索)使用分离,其余部分依赖于公共实体框架模型。

最终,我们的想法是,您应该使用使查询通道最容易构建和维护的任何工具。您不再需要担心更新、强制执行业务规则、维护数据完整性甚至处理负载(大部分情况下)。因此,您可以自由选择许多以前不在桌面上的选项

但NHibernate仍然是一个不错的选择。。。它不再是自动默认值(有时是用于命令端)


我们选择使用Castle Active Record(它基于NHibernate Underthe hood),主要是因为它有一个很好的特性,可以从类中为您生成一个表。这非常适合我们,因为我们的工作流程如下:首先,我们创建一个ViewModel类。这个类完全是为视图的需要而设计的。然后,我们用Castle活动记录属性标记ViewModel。然后,我们要求活动记录在查询数据库中为该类生成相应的表。这是我们发现的快速获取为ViewModel类服务的查询数据库表的最快、最平滑的方法。自动生成反映了这样一个事实,即表存在的唯一原因是为视图服务。

我喜欢将ORM的读写分开,以便使用(我使用):

Nhibernate用于命令-完美地映射我的域模型

Dapper.net用于查询-完美地映射我的DTO,并在查询过于复杂时允许灵活性


他们是完美的一对,就像汉·索洛和丘巴卡一样。

我明白你说的两个不同的类来明确区分的意思,我同意。但是,如果我只是为了创建DTO而进行查询,那么我真的想使用ORM来实现这一点吗?我不需要变更跟踪或工作单元。我喜欢投影/映射,但我的查询端DTO与我的命令对象图无关,查询有时很复杂——在视图或存储过程中编写比在HQL或使用条件更容易。为查询DTO创建视图怎么样?对某些人来说很好,但对所有人来说?我不确定我是否想在NHib的n个表之间映射,只是为了获取一个DTO。THX.我明白你的意思,我确实很难让HQL在加入几个表时做我想做的事情。我想,如果您有一个接口定义了用于查询的方法,那么最终实现并不重要。对接口进行编码,并使用有意义的代码。也许它是Nhibernate、ADO.NET或所有ADO.NET的混合体。如果您在以后的选择中发现了一个弱点,那么使用有意义的技术实现一个新的具体类。在这个场景中,您肯定最清楚什么是正确的,而且听起来ORM没有在您的sce中添加任何内容