【问题标题】:Override Json Serialization RavenDB覆盖 Json 序列化 RavenDB
【发布时间】:2014-09-30 14:46:54
【问题描述】:

我正在试验 RavenDB。根据以下(简单)示例,我们有大量使用属性装饰的实体对象:

[Entity(UniqueID = "37AA8322-597D-48E8-BB66-7B2796103D95")]
public class SampleEntity : Entity
{
    protected SampleEntity()
    {

    }

    public static SampleEntity Create()
    {
        return EntityFactory.Create<SampleEntity>();
    }

    [Property]
    public virtual int Integer { get; set; }
}

EntityFactory 发出的类型实际上是 SampleEntity 的子类,它覆盖 setter/getter,自动实现 INotifyPropertyChanged 并跟踪每个属性的最后修改时间(除其他外)。

使用 Json.NET,我为实体组合了一个 Json 序列化程序,对于将“整数”设置为 8 的 SampleEntity 实例,它会输出类似于以下内容的内容:

{
  "TypeID": "\"37aa8322-597d-48e8-bb66-7b2796103d95\"",
  "UniqueID": "\"e1f03e21-260f-4bde-8bfb-ec7a47b2e379\"",
  "Integer": {
    "Last Set": "2014-09-30T14:06:08.9146417Z",
    "Value": "8"
  }
}

注意“Integer”属性是如何扩展为包括“Value”和“Last Set”的。如果我要求 RavenDB 存储一个 SampleEntity,我(如预期的那样)不会将“Last Set”与“Value”内联(在基类中,有一个字典将属性名称映射到有关该属性的信息,一个字段是当属性是最后设置的)。

理想情况下,我想存储我在 RavenDB 中编写的 Json-Entity 序列化程序的输出(使用为每个实体自动生成的 UniqueID 作为文档 ID)。当我检索文档时,它将是原始 json,我将负责使用它来水合适当的实体对象。我进行了广泛的搜索,但找不到一种简单的方法来实现这一点,这在历史上意味着我正在尝试做一些愚蠢的事情。

我对 RavenDB(一般的文档数据库)和 Json 都很陌生,所以也许我想在这里将一个方形钉塞进一个圆孔中,并且有一种更优雅的方式来处理这种情况。

有人知道在 RavenDB 中存储原始 json 的方法吗?或者对我可以完成我所描述的其他方式有任何 cmets/建议?

【问题讨论】:

    标签: c# json serialization ravendb


    【解决方案1】:

    一种选择是使用转换器来自定义写入数据库的 RavenJObject,并自定义填充所需返回对象的方式。

    这里有一些代码:

    public class SampleEntityConverter : IDocumentConversionListener
    {
        public void EntityToDocument(string key, object entity, RavenJObject document, RavenJObject metadata)
        {
            var obj = entity as SampleEntity;
            if (obj == null)
            {
                return;
            }
    
            var integer = new RavenJObject();
            integer["Last Set"] = obj.HoweverYouGetTheLastSetDateTime;
            integer["Value"] = obj.Integer;
            document["Integer"] = integer;
        }
    
        public void DocumentToEntity(string key, object entity, RavenJObject document, RavenJObject metadata)
        {
            var obj = entity as SampleEntity;
            if (obj == null)
            {
                return;
            }
    
            var integer = document["Integer"] as RavenJObject;       
            if (integer != null && integer.ContainsKey("Value"))
            {
                obj.Integer = integer["Value"];
            }
        }
    }
    

    然后在您的 DocumentStore 实例上注册它:

    documentStore.RegisterListener(new SampleEntityConverter());
    

    【讨论】:

      【解决方案2】:

      您可以使用 RavenDB 使用的 JSON.Net 的内部化副本注册相同的转换器。 在 Conventions 中,查看 CustomizeSerialize 方法

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-02-05
        • 2016-02-09
        • 2014-03-18
        • 1970-01-01
        • 1970-01-01
        • 2019-05-23
        • 2013-10-02
        相关资源
        最近更新 更多