I am trying to learn CQRS in my spare time. Say I have a class like this:
public class Person
{
private Guid Id {get; set;}
private Guid Name {get; set;}
private List<Order> orders;
//Methods and constructor go here
}
I am thinking of a scenario where it would be beneficial to persist the Person class to the write database (SQL Server) and then the person and order class to the read database (Mongodb).
The only reason I need to persist the Person class on the write side is to benefit from change tracking.
Is it normal for the write database to have different fields to the read database i.e. in this case orders are not persisted on the write side. Or should the same classes and fields be persisted on both sides?
I realise that relational databases are different to NoSQL databases and both have their benefits and limitrations. I am specifically asking if it is normal for information to be available in the read database that is not available in the write database.
I realise the answer to my question is yes; from a technical point of view. I am asking when thinking about the principle of least astonishment.
Update 20/01/19
Here is a sample of code from the write side domain model:
public class Product
{
public Guid Id { get; set; }
public string Code { get; set; }
public string Description { get; set; }
public void LookupDescriptionByCode(List<ProductDescriptionLookup> productCodes)
{
Description = productCodes.Find(x => x.Code == Code).Description;
}
}
public class ProductDescriptionLookup
{
public Guid Id { get; set; }
public string Code { get; set; }
public string Description { get; set; }
}
The database (lookup tables) looks like this:
create table ProductDescriptionLookup(Id uniqueidentifier, Code varchar(100), Description varchar(100))
insert into ProductDescriptionLookup (Id,Code,[Description])
values (newid(), 'prod1','Product1')
Here is some test code for the write side:
[Fact]
public void Test()
{
List<ProductDescriptionLookup> list = new List<ProductDescriptionLookup>();
list.Add(new ProductDescriptionLookup { Id = Guid.NewGuid(), Code= "prod1", Description="Product1" });
Product p1 = new Product { Id = Guid.NewGuid(), Code = "prod1", Description = "" };
p1.LookupDescriptionByCode(list);
}
Here is the read model (which is mapped to a MongoDB database):
public class Product
{
public Guid Id { get; set; }
public string Description { get; set; }
}
Notice that the Product Code is not even persisted to the read side. Therefore there is no need for the lookup table on the read side (because it will never have to lookup the description by product code). Therefore I am planning to exclude the ProductDescriptionLookup table from the read side. This works perfectly from a technical point of view, however I am wandering if it is frowned upon as the read database is now different to the write database.