【问题标题】:Json.NET serialise root object differently to descendant objectsJson.NET 序列化根对象与后代对象不同
【发布时间】:2014-04-27 19:45:29
【问题描述】:

我正在使用 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 中)来执行此操作,但这会在序列化之后发生(似乎是多余的)并且会涉及反射(尽管会考虑,但我更愿意避免)。

我也在拼命地避免编写单独的持久性类,其中包含所有需要的转换逻辑......

我希望一切都有意义。

【问题讨论】:

  • 如果您不想要子类,为什么不直接将 Parent 设为字符串而不是对象?
  • 感谢您的评论。我需要它用于 Group 类中的业务逻辑(为简洁起见)。但是,我不想为每个组存储父组,因为当您考虑父组可以拥有自己的父组等等时,这似乎是多余的并且非常昂贵。我的意图是在需要时延迟加载它。不过,我现在正在花时间重新考虑域模型,看看是否可以避免此类问题。

标签: json.net ravendb aggregateroot


【解决方案1】:

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

但是,对于大型结构,这可能是不可取的,因此我正在重新审视我的领域模型,以了解我是否需要担心这些问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多