3

C# ドライバーを使用して MongoDB を操作しています。問題は、いくつかの共通フィールドと異なる詳細フィールドを使用して、MongoDB にさまざまな種類のオブジェクトを格納したいということです。異なるクライアントは、データベース内の異なるタイプを処理します。

コードは次のようになります。

class Things
{
    public string Name {get;set;}
    public string User { get; set; }
    public ObjectId Id { get; set; }

    public virtual Dictionary<string, object> Details { get; set; }
}

class Pc:Things
{
    public new Detail Details { get; set; }
}

class Detail
{
    public string cpu { get; set; }
    public int ram { get; set; }
    public int hdd { get; set; }
}

クエリを実行して PC オブジェクトを取得しようとすると、Details プロパティが Thing で使用されているため PC では使用できないという例外がスローされます。オブジェクトの逆シリアル化中に期待がスローされると思います。

別のクラスを作成すると:

class Pc2
{
    public string Name { get; set; }
    public string User { get; set; }
    public ObjectId Id { get; set; }
    public Detail Details { get; set; }
}

これは Thing と同じですが、Details を Detail タイプとして使用すると、すべてが機能します。

私はこれを間違っていますか?または、これは CSharpDriver の将来のバージョンで可能になりますか?

4

1 に答える 1

2

【説明】

あなたの質問とコメントを読み直して、あなたの問題に間違って対処したことに気づきました。new キーワードの使用は違法ではありません - コンパイラは、同じ名前のプロパティを持つ派生クラスで異なる型を返すことを許可します - 何が起こるかは、派生クラスの Details プロパティが独立していることをコンパイラに伝えることですその親クラス。

これを行っているときは、多くの場合、クラス階層がよく考えられていないことを示しているため、最初の投稿で独断的でした。

あなたの場合(DetailsMongoDbで異なる共通クラスを保存しようとしている)、多態的なクラス階層を使用して、MongoDbドライバーのシリアル化自動マッピングに違反しています。必要なことを行うには、MongoDbドキュメントで説明されているように、クラスのマッピングを明示的に登録する必要があります。ドキュメントの関連部分を引用する:

[出典: MongoDb ドキュメント]

RegisterClassMap を (引数なしでも) 自分で呼び出さなければならない 1 つのケースは、ポリモーフィックなクラス階層を使用している場合です。この場合、すべての既知のサブクラスを登録して、弁別子が登録されることを保証する必要があります。

于 2013-09-05T06:42:09.537 に答える