在RavenDB的某些字段中存储具有空值的实体

时间:2013-05-06 11:24:54

标签: c# nosql ravendb

我正在使用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数据库,而不在我没有设置的字段中获取空值?在最后一段代码之后,我的db看起来像:

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

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

{
 HostAlias : "bla",
 IsCancelled : 0
}

是否为空值?

3 个答案:

答案 0 :(得分:2)

使用此保存在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;

答案 1 :(得分:1)

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

我喜欢使用RavenDb并且拥有NULL属性对我来说非常棒并且很有帮助。我相信如果属性存在于DB中而不存在于类中(因为您的类'schema'已经更改),那么它将忽略该db属性/值。

也就是说,您可以告诉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 :))

答案 2 :(得分:0)

我相信raven会将你的对象(及其所有属性)映射到Json对象并保存它。因此全部 你的对象属性将被保留。

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

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

这有帮助吗?

编辑:

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

听起来怎么样? :P