問題
プロパティがある場合dynamic
、RavenDB は常にそれを として逆シリアル化しRavenJObject
ます。例えば:
public class User {
public dynamic Data = new ExpandoObject();
}
...
var user = new User();
user.Data.SomethingNew1 = "foo";
これは無害に見え、ユーザーを作成するときに正常に機能します。しかし、ユーザーをロードすると、RavenDB は必要なタイプがわからないdynamic
ため、 を使用しますRavenJObject
。プロパティ (expando スタイル) を動的に作成することはできないRavenJObject
ため、これは失敗します。
var user = session.Find<User>(...);
user.Data.SomethingNew2 = "foo"; //compiles, but throws
私の解決策
を使用し、ExpandoObject
シリアル化されたプロパティでその型を明示的に定義します。これにより、RavenDB (または私が推測する JSON) は、あなたが期待している型を知ることができ、推測する必要はありませんRavenJObject
。次に、構文マジックを維持するために、プロパティを動的アクセサーでラップします。
public class User {
public ExpandoObject _Data = new ExpandoObject();
public dynamic Data {
get { return _Data; }
}
}
expando オブジェクトを非公開にする方法と のセッターを作成する方法がありますが、Data
アイデアはわかります。
その他の問題
更新: 残念ながら、この解決策にはさらに問題があります。動的データに文字列のリストを保存するとします。
user.Data.Keys = new List<String>{"a","b","c"};
シリアル化/逆シリアル化した後、JSON/Raven は期待している型を再び認識しません。したがって、これを試してみると (以下を参照)、コンパイルされますが、実行時例外が発生します Cannot implicitly convert type 'Raven.Abstractions.Linq.DynamicList' to 'System.Collections.Generic.List' :
List<string> keys = user.Data.Keys;