MongoDb中的继承:如何请求已定义类型的实例

YMC*_*YMC 4 polymorphism mongodb c#-4.0 mongodb-query mongodb-.net-driver

这就是我过去在实体框架(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
Run Code Online (Sandbox Code Playgroud)

这是我在MongoDb(MongoDb参考)中找到的唯一类似方式:

var query = Query.EQ("_t", "Cat");
var cursor = collection.FindAs<Animal>(query);
Run Code Online (Sandbox Code Playgroud)

注意在后一种情况下,我必须处理鉴别器("_ t")并硬编码我的类名,这不太方便,看起来很糟糕.如果我错过了查询,我在枚举尝试中得到了一个例外.我错过了什么吗?我的建议是文件Db,它存储对象'应该'容易处理继承.

Bob*_*nks 10

假设您的鉴别器正在运行(_t正确存储每个文件),那么我认为这正是您所寻找的.

var results = collection.AsQueryable<Animal>().OfType<Cat>
Run Code Online (Sandbox Code Playgroud)

仅返回"Cat"类型的文档.


moo*_*000 5

好吧,文档数据库实际上“按原样”存储对象 - 即没有属于某个特定类的对象的概念。这就是为什么_t当您希望解串器知道要实例化哪个子类时需要的原因。

就您而言,我建议您为每个子类提供一个鉴别器,而不是依赖于类名。这样,您可以重命名类等,而不必担心某处的硬编码字符串。

你可以这样做:

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

[BsonDiscriminator(SomeBaseClass.FirstSubClass)]
public class FirstSubClass { ... }
Run Code Online (Sandbox Code Playgroud)

进而

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

var subs = entireCollection.Find(Query.Eq("_t", SomeBaseClass.FirstSubClass));
Run Code Online (Sandbox Code Playgroud)