1

I am using RavenDB (which itself uses Json.NET) to store documents (or aggregate roots).

When I store an aggregate root, I would like the aggregate roots it references (either directly or indirectly as a descendant of another reference) to only serialise their Id properties...

The reason being that I don't need the data duplication.

An example:

public abstract class Entity
{
    public string Id { get; set; }
}

public abstract class AggregateRoot : Entity
{
}

public class Address : Entity
{
    public string City { get; set; }
}

public class Group : AggregateRoot
{
    public string Name { get; set; }
    public Address Address { get; set; }
    public Group Parent { get; set; }
}

If I serialise (or store):

new Group
{
    Id = "groups/2",
    Name = "Child",
    Address = new Address
    {
        City = "London"
    },
    Parent = new Group
    {
        Id = "groups/1",
        Name = "Parent"
    }
}

I will get:

{
    "Id": "groups/2",
    "Name": "Child",
    "Address":
    {
        "City": "London"
    },
    "Parent":
    {
        "Id": "groups/1",
        "Name": "Parent"
    }
}

I would prefer:

{
    "Id": "groups/2",
    "Name": "Child",
    "Address":
    {
        "City": "London"
    },
    "Parent":
    {
        "Id": "groups/1"
    }
}

In other words I want the top level aggregate root to have all it's properties, but any descendant aggregate root to only have it's Id property. Please note that Address (which is not an aggregate root) is retained.

I thought about doing this with a document conversion listener (in RavenDB) but that would occur after serialisation (seems redundant) and would involve reflection (which I'd prefer to avoid although will consider).

I am also desperately trying to avoid writing separate persistence classes with all the conversion logic that would entail...

I hope that all makes sense.

  • Why not just make Parent a string instead of an object if you don't want the sub class? – Shawn C. Apr 23 '14 at 15:37
  • Thanks for the comment. I need it for business logic (not presented for brevity) inside the Group class. However I do not want to store the parent for each Group because it seems redundant and quite costly when you consider a parent Group can have it's own parent Group and so on. My intention was to lazily load it when required. However I am now taking the time to rethink the domain model to see whether I can avoid issues such as this. –  Apr 27 '14 at 11:55

1 Answers1

0

I ended up post-processing the document by turning on Json.NET's "all" type name handling and by registering my own RavenDB conversion listener. This allowed me to walk the JSON structure, find aggregate roots by the $type property and then act accordingly.

However, this is probably not advisable with large structures and therefore I am taking another look at my domain model to understand whether or not I need to worry about such issues at all.