4

これは、Entity Framework (POCO) で継承を利用するために使用した方法です。

ctx.Animals // base class instances (all instances)
ctx.Animals.OfType<Cat>  // inherited class Cat's instances only
ctx.Animals.OfType<Dog> // inherited class Dog's instances only

これは、MongoDb で見つけた唯一の同様の方法です ( MongoDb 参照):

var query = Query.EQ("_t", "Cat");
var cursor = collection.FindAs<Animal>(query);

後者の場合、ディスクリミネータ ("_t") を処理し、クラス名をハードコーディングする必要があることに注意してください。これはあまり便利ではなく、見栄えも悪くなります。クエリに失敗すると、列挙の試行で例外が発生しました。私は何かを逃しましたか?私の提案は、オブジェクトを「そのまま」保存するドキュメント Db が継承を簡単に処理できるようにすることでした。

4

5 に答える 5

4

ドキュメント データベースは、実際にはオブジェクトを「そのまま」格納します。つまり、オブジェクトが特定のクラスに属するという概念はありません。そのため_t、デシリアライザーにインスタンス化するサブクラスを認識させたい場合に必要です。

あなたの場合、クラス名に頼るのではなく、各サブクラスの識別子を考え出すことをお勧めします。このようにして、どこかにハードコードされた文字列を心配することなく、クラスなどの名前を変更できます。

次のようなことができます。

public abstract class SomeBaseClass
{
    public const string FirstSubClass = "first";
    public const string SecondSubClass = "second";
}

[BsonDiscriminator(SomeBaseClass.FirstSubClass)]
public class FirstSubClass { ... }

その後

var entireCollection = db.GetCollection<FirstSubClass>("coll");

var subs = entireCollection.Find(Query.Eq("_t", SomeBaseClass.FirstSubClass));
于 2012-05-02T07:06:43.787 に答える
1

あなたのリンクから:

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


基本クラスと各派生クラスのクラス マップを登録します。

BsonClassMap.RegisterClassMap<Animal>();
BsonClassMap.RegisterClassMap<Cat>();
BsonClassMap.RegisterClassMap<Dog>();

コレクションが基本クラスの型であることを確認してください。

collection = db.GetCollection<Animal>("Animals");

クエリを使用して検索します。対応する子クラスへの変換は自動的に行われます。

var query = Query.EQ("_t", "Cat");
var cursor = collection.Find(query);
于 2013-04-05T16:22:56.423 に答える
0

唯一の懸念がクラス名のハードコーディングである場合は、次のようにすることができます。

collection = db.GetCollection<Animal>("Animals");
var query = Query.EQ("_t", typeof(Cat).Name);
var cursor = collection.Find(query);
于 2014-04-03T10:00:44.110 に答える