Json.NET序列化根对象与后代对象不同

时间:2014-04-18 18:31:53

标签: json.net ravendb aggregateroot

我正在使用RavenDB(它本身使用Json.NET)来存储文档(或聚合根)。

当我存储聚合根时,我希望它引用的聚合根(直接或间接作为另一个引用的后代)仅序列化它们的Id属性...

原因是我不需要重复数据。

一个例子:

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; }
}

如果我序列化(或存储):

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

我会得到:

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

我更愿意:

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

换句话说,我希望顶级聚合根拥有它的所有属性,但任何后代聚合根只能拥有它的Id属性。请注意,地址(不是聚合根)将被保留。

我考虑过使用文档转换监听器(在RavenDB中),但这会在序列化之后发生(似乎是多余的)并且会涉及反射(虽然我会考虑,但我更愿意避免)。

我也拼命地试图避免用所有需要的转换逻辑编写单独的持久化类...

我希望一切都有道理。

1 个答案:

答案 0 :(得分:0)

我最终通过打开Json.NET"所有"来对文档进行后期处理。类型名称处理和注册我自己的RavenDB转换监听器。这允许我遍历JSON结构,通过$ type属性找到聚合根,然后相应地采取行动。

然而,这可能不适用于大型结构,因此我会再看看我的域模型,以了解我是否需要担心这些问题。