这就是我如何利用利用继承的实体框架(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应该很容易处理继承。
假设你的鉴别器正在运作(_t正确保存每个文档),那么我认为这是你在找什么。
var results = collection.AsQueryable<Animal>().OfType<Cat>
只返回类型为“猫”的文档。
那么,文档数据库做实际上存储对象“原样” - 即不属于某个特定类对象的概念。 这就是为什么你需要_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));
从你的链接 :
在一个情况下,你必须调用RegisterClassMap自己(甚至无参数)是当你使用多态类层次结构:在这种情况下,你必须注册所有已知的子类,以保证鉴别获得注册。
注册您的基类,类映射和派生类中的每一个:
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);
如果只关心的是硬编码的类名,你可以这样做:
collection = db.GetCollection<Animal>("Animals");
var query = Query.EQ("_t", typeof(Cat).Name);
var cursor = collection.Find(query);
就拿文件一看http://docs.mongodb.org/ecosystem/tutorial/serialize-documents-with-the-csharp-driver/#scalar-and-hierarchical-discriminators
您可以选择使用分级鉴别主要的原因是因为它使得可能来查询层次结构中的任何一类的所有实例。 例如,读取所有我们可以写猫的文件:
var query = Query.EQ("_t", "Cat");
var cursor = collection.FindAs<Animal>(query);
foreach (var cat in cursor) {
// process cat
}