The principle behind the CQS architectural pattern is that you separate your queries and commands into distinct paths. Ideally, your persistence store can be read/write partitioned, but in my case, there is a single, normalized database.
If you are using an ORM (NHibernate in my case), it's clear that the ORM is used when issuing commands. But what about all the various queries you need to run to shape data (DTOs) for user screens, is it common practice to ditch the ORM when doing the Query side of CQS?
Where should I implement my queries and DTO projections? Straight ADO.NET (datareaders, dtos, datatables, stored procs)? Some queries are quite unique and involve a lot of joins to pull everything together. I don't want to denormalize the database for the queries, but I could create views (poor man's denormalization).
Command query responsibility segregation (CQRS) is a programming design pattern that treats retrieving data and changing data differently. CQRS uses command handlers to simplify the query process and hide complex, multi-system changes.
Command-query separation (CQS) is a principle of imperative computer programming. It was devised by Bertrand Meyer as part of his pioneering work on the Eiffel programming language. It states that every method should either be a command that performs an action, or a query that returns data to the caller, but not both.
The CQS pattern states one thing clearly: a Command can only mutate state and cannot have a return value. As I implement this pattern into an architecture, I allow (or even enforce) Commands to have a return value. The main reason to follow the CQS pattern is to keep code readable and reusable.
I'm assuming by CQS you mean the DDD architectural pattern aka CQRS, not strictly the traditional CQS principle.
I'd still use NHibernate for your read only model. There are many advantages such as future and multi queries, lazy/eager loading etc... that will optimize DB chattiness. Additionally, it will be easier to compose queries with an ORM if the UI allows for the user to essentially change the where clause.
Regarding how to technically handle a read only model, you can mark an entity immutable with NHibernate. You could simply mark all of your read model entities immutable. Also, I don't think you can update projections in NHibernate so that is another option to go for as your read only model (Someone please correct me if I am wrong as I am not 100% sure).
Regarding ugly or impossible NH mappings: NH can map to views and stored procedures, so I think it would be fine to use these when you need to. Views are probably a bit more flexible than stored procedures for a read only scenario because your SQL will still be dynamic. However, If you need read / write for any of these flattened structures I'd map to a store procedure.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With