I'm using RavenDB & need to store dynamic data like:
public class User {
public string Name;
public dynamic Data;
}
It appears that I could use many different types such as dynamic
, RavenJObject
, DynamicJsonObject
, ExpandoObject
, Dictionary<string, object>
, but I don't know what the differences are.
Could someone explain the options for dynamic data? I care less about querying & more about easy storage & retrieval.
Here's the deal, if you have a dynamic
property then RavenDB will always deserialize it as a RavenJObject
. For example:
public class User {
public dynamic Data = new ExpandoObject();
}
...
var user = new User();
user.Data.SomethingNew1 = "foo";
This looks harmless & works fine when you create your user. But when you Load user, RavenDB doesn't know what type you want for dynamic
so it uses RavenJObject
. You can't dynamically create properties (expando style) with RavenJObject
so this fails:
var user = session.Find<User>(...);
user.Data.SomethingNew2 = "foo"; //compiles, but throws
Use an ExpandoObject
and explicitly define its type in the property that is serialized. That lets RavenDB (or JSON i guess) know what type you're expecting & it doesn't have to guess RavenJObject
. Then, to keep your syntactical magic, wrap the property with a dynamic accessor.
public class User {
public ExpandoObject _Data = new ExpandoObject();
public dynamic Data {
get { return _Data; }
}
}
There are ways to make the expando object private & to create a setter for Data
, but you get the idea.
Update: Unfortunately this solution exposes more problems. Say you store a list of strings in your dynamic data:
user.Data.Keys = new List<String>{"a","b","c"};
After you serialize/deserialize, JSON/Raven again doesn't know what type you are expecting. So if you try this (see below) then it compiles but you get a runtime exception Cannot implicitly convert type 'Raven.Abstractions.Linq.DynamicList' to 'System.Collections.Generic.List':
List<string> keys = user.Data.Keys;
For all of those, it doesn't really matter what your in memory type is.
object, dynamic and DynamicJsonObject are the same thing - as far as RavenDB is concerned. It gives you a dynamic implementation using RavenJObject as the backend for that.
RavenJObject is literally just the value that you get from the server.
ExpandoObject and Dictionary are serialized to/from dictionary, is all.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With