9

RavenDBを使用していて、次のような動的データを保存する必要があります。

public class User {
    public string Name;
    public dynamic Data;
}

、、、、、など、さまざまなタイプを使用できるようdynamicですが、RavenJObject違い はわかりません。DynamicJsonObjectExpandoObjectDictionary<string, object>

誰かが動的データのオプションを説明できますか?私はクエリをあまり気にせず、簡単な保存と取得を重視しています。

4

2 に答える 2

6

問題

プロパティがある場合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;
于 2012-04-09T16:00:41.723 に答える
4

これらすべてについて、メモリ内のタイプが何であるかは問題ではありません。

object、dynamic、および DynamicJsonObject は、RavenDB に関する限り、同じものです。そのためのバックエンドとして RavenJObject を使用して、動的な実装を提供します。

RavenJObject は文字通り、サーバーから取得する値にすぎません。

ExpandoObject と Dictionary は、辞書との間でシリアライズされます。

于 2012-04-09T06:30:23.340 に答える