【问题标题】:Storing entity with null values in some fields in RavenDB在 RavenDB 的某些字段中存储具有空值的实体
【发布时间】:2018-09-24 23:07:07
【问题描述】:

我正在使用 RavenDB(NoSQL 数据库),并且我有这个类:

public class VirtualDirectory
    {   
        public string Id { get; set; }
        public string HostAlias { get; set; }
        public string VirtualPath { get; set; }
        public string IdentificationMethod { get; set; }
        public int IsCancelled { get; set; }
    }

我正在通过以下方式启动此类的新实例:

VirtualDirectory vd = new VirtualDirectory() { HostAlias = "bla", IsCancelled = 0 };

并通过以下方式保存文档:

using (var session = DbConnection.Instance.DocumentStore.OpenSession(DbName))
            {
                session.Store(vd);
                session.SaveChanges();
            }

根据我对 NoSQL DB 文档的了解,这些文档没有绑定到架构,因此它们的结构很灵活。

我的问题是: 如何将数据保存到我的 RavenDB 数据库,而不会在我未设置的字段中获得空值?在最后一段代码之后,我的数据库看起来像:

{
 HostAlias : "bla",
 VirtualPath : null,
 IdentificationMethod : null,
 IsCancelled : 0
}

当我得到一个缺少某些字段的 C# 对象(VirtualDirectory 类型)时:

{
 HostAlias : "bla",
 IsCancelled : 0
}

会是空值吗?

【问题讨论】:

    标签: c# nosql ravendb


    【解决方案1】:

    使用它保存在 ravendb 中:

    store.Conventions.CustomizeJsonSerializer = serializer => serializer.NullValueHandling=NullValueHandling.Ignore;
    

    获取和返回数据:

    var config = GlobalConfiguration.Configuration;
    
    var settings = config.Formatters.JsonFormatter.SerializerSettings;
    
    settings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
    

    【讨论】:

      【解决方案2】:

      就个人而言,我不确定您为什么要避免在数据库中使用 null 属性。

      我喜欢使用 RavenDb 并且拥有 NULL 属性对我来说非常棒并且很有帮助。我相信如果该属性存在于数据库中但不存在于类中(因为您的类“架构”已更改),那么它将忽略该数据库属性/值。

      也就是说,您可以告诉 RavenDb 在将某些内容保存到数据库时要做什么。 You can customize the serialization/deserialization process。在这里,您需要创建一个自定义 ContractResolver

      在这种情况下,您需要检查当前值是否为空。如果是,则忽略此属性。

      所以,这是 150% 未经测试的,只是在快速谷歌搜索后写在这里。将其作为参考。

      public class IgnoreNullValuesContractResolver : DefaultRavenContractResolver
      {
          public IgnoreNullValuesContractResolver(bool shareCache)
              : base(shareCache)
          {
          }
      
          protected override JsonProperty CreateProperty(MemberInfo member,
                                                         MemberSerialization memberSerialization)
          {
              // Grab the property.
              var property = base.CreateProperty(member, memberSerialization);
      
              // Only write this property if the value is NOT null.
              // NOTE: I have no idea if this is the correct way to retrieve
              //       the reflected property and it's value. 
              property.Writable = ((PropertyInfo) member).GetValue(member, null) != null;
      
              return property;
          }
      }
      

      GL :)

      【讨论】:

        【解决方案3】:

        我相信 raven 会将您的对象(及其所有属性)映射到 Json 对象并保存它。因此所有 您的对象属性将被持久化。

        我会制作另一个对象——它只有我需要的属性——并将其保存到数据库中。

        如果您将 VirtualDirectory 类保存到 raven - 您将使用空值取回它,因为 raven 将实例化您的对象 - 然后填写它具有值的属性。

        这有帮助吗?

        编辑:

        根据您的评论,我做了一个小实验,发现使用“动态”可以很容易地实现您所需要的。 Raven 会很好地存储它,但它们不会自动聚合到集合中。

        听起来怎么样? :P

        【讨论】:

        • 为每个可能的属性组合创建对象是没有意义的..
        • ofc 不是——我以为你只是想要你指定为对象子集的 2 个属性
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-02
        • 1970-01-01
        • 2019-10-08
        • 1970-01-01
        • 2021-01-25
        • 2015-12-24
        相关资源
        最近更新 更多