persistence - How to correctly model loosely-typed properties in RavenDB -
persistence - How to correctly model loosely-typed properties in RavenDB -
i new ravendb , looking guidance on right way store loosely-typed data. have type list of key/value pairs. type of value property isn't known @ design time.
public class descriptivevalue { public string key { get; set; } public object value { get; set; } }
when query descriptivevalue saved datetime or guid value, deserialized info type string. numeric values appear retain info types.
is there elegant solution retain info type or should store values strings? if go string route, limit me when later want sort , filter info (likely via indexes?)
i hoping mutual problem solved , i'm thinking problem incorrectly. help much appreciated!
update: output of unit test is: assert.areequal failed. expected:<2/2/2012 10:00:01 (system.datetime)>. actual:<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); } }
i expect actual datetime value.
the problem ravendb server has no notion of type of value
. when sending object server, value
persisted string, , when later query document, deserializer not know original type, value
deserialized string.
you can solve adding original type info objectvaluedattribute
:
public class objectvaluedattribute { private object _value; public string key { get; set; } public object value { { // convert value original type if (valuetype != null && _value.gettype() != valuetype) { _value = typedescriptor .getconverter(valuetype).convertfrom(_value); } homecoming _value; } set { _value = value; valuetype = value.gettype(); } } public type valuetype { get; private set; } }
in setter of value
store type of it. later, when getting value, convert original type.
following test passes:
class="lang-cs prettyprint-override">public class codechef : localclienttest { public class objectvaluedattribute { private object _value; public string key { get; set; } public object value { { // convert value original type if (valuetype != null && _value.gettype() != valuetype) { _value = typedescriptor .getconverter(valuetype).convertfrom(_value); } homecoming _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); } } } }
persistence ravendb json.net
Comments
Post a Comment