如何在RavenDB中正确建模松散类型的属性



我是RavenDB的新手,正在寻找关于存储松散类型数据的正确方法的指导。我有一个带有键/值对列表的类型。value属性的类型在设计时未知。

public class DescriptiveValue
{
    public string Key { get; set; }
    public object Value { get; set; }
}

当我查询使用DateTime或Guid值保存的DescriptiveValue时,反序列化的数据类型为字符串。数值显示为保留其数据类型。

有没有一个优雅的解决方案来保留数据类型,或者我应该简单地将所有值存储为字符串?如果我走字符串路线,这会限制我以后想要排序和过滤这些数据(可能通过索引?)吗

我希望这是一个很容易解决的常见问题,但我只是错误地思考了这个问题。非常感谢您的帮助!

更新:此单元测试的输出为:Assert.AreEqual失败。应为:<2012年2月2日上午10:00:01(System.DateTime)>。实际:<2012-02-02T10:00:01.9047999(System.String)>.

[TestMethod]
public void Store_WithDateTime_IsPersistedCorrectly()
{
    AssertValueIsPersisted<DateTime>(DateTime.Now);
}
private void AssertValueIsPersisted<T>(T value)
{
    ObjectValuedAttribute expected = new ObjectValuedAttribute() { Value = value };
    using (var session = this.NewSession())
    {
        session.Store(expected);
        session.SaveChanges();
    }
    TestDataFactory.ResetRavenDbConnection();
    using (var session = this.NewSession())
    {
        ObjectValuedAttribute actual = session.Query<ObjectValuedAttribute>().Single();
        Assert.AreEqual(expected.Value, actual.Value);
    }
}

我希望实际值是DateTime值。

绝对-这是无模式文档数据库的优势之一。请参见此处:http://ravendb.net/docs/client-api/advanced/dynamic-fields

问题是RavenDB服务器没有Value类型的概念。当将对象发送到服务器时,Value将被持久化为字符串,而当您稍后查询该文档时,反序列化程序不知道原始类型,因此Value将被反序列化为字符串。

您可以通过将原始类型信息添加到ObjectValuedAttribute:来解决此问题

public class ObjectValuedAttribute {
    private object _value;
    public string Key { get; set; }
    public object Value {
        get {
            // convert the value back to the original type
            if (ValueType != null && _value.GetType() != ValueType) {
                _value = TypeDescriptor
                    .GetConverter(ValueType).ConvertFrom(_value);
            }
            return _value;
        }
        set { 
            _value = value;
            ValueType = value.GetType();
        }
    }
    public Type ValueType { get; private set; }
}

Value的setter中,我们还存储了它的类型。稍后,当获取值时,我们将其转换回原始类型。

以下测试通过:

public class CodeChef : LocalClientTest {
    public class ObjectValuedAttribute {
        private object _value;
        public string Key { get; set; }
        public object Value {
            get {
                // convert value back to the original type
                if (ValueType != null && _value.GetType() != ValueType) {
                    _value = TypeDescriptor
                        .GetConverter(ValueType).ConvertFrom(_value);
                }
                return _value;
            }
            set { 
                _value = value;
                ValueType = value.GetType();
            }
        }
        public Type ValueType { get; private set; }
    }
    [Fact]
    public void Store_WithDateTime_IsPersistedCorrectly() {
        AssertValueIsPersisted(DateTime.Now);
    }
    private void AssertValueIsPersisted<T>(T value) {
        using (var store = NewDocumentStore()) {
            var expected = new ObjectValuedAttribute { Value = value };
            using (var session = store.OpenSession()) {
                session.Store(expected);
                session.SaveChanges();
            }
            using (var session = store.OpenSession()) {
                var actual = session
                    .Query<ObjectValuedAttribute>()
                    .Customize(x => x.WaitForNonStaleResults())
                    .Single();
                Assert.Equal(expected.Value, actual.Value);
            }
        }
    }
}

相关内容

  • 没有找到相关文章

最新更新