我有Mongo Collection
个TaskBase
个文件。 TaskBase
有三个子类。我为这个集合创建了一个集合管理器(来自我已经使用过的通用管理器)。当我创建,更新或检索TaskBase
的子类时,我得到了正确的类型,没有例外。
我创建了以下方法:
public IEnumerable<TaskBase> GetTasksByAppId(string appId)
{
var entityQuery = Query<TaskBase>.EQ(t => t.AppOId, appId);
return this.MongoConnectionHandler.MongoCollection.Find(entityQuery).ToList();
}
当我运行这个时,我得到一个例外Element [some element existing only in a subclass] is not a property or member of TaskBase
我理解为什么我会得到这个例外,我只是不知道该怎么做。
我想获得可以与App关联的所有类型的任务的集合。
答案 0 :(得分:5)
您需要向驱动程序显示您的类层次结构。共有2个选项,第一个使用BsonKnownTypes
和BsonDiscriminator
属性,另一个使用BsonClassMap
。
使用您想要包含的特定派生类来装饰您的基类(类似于您在WCF
中的操作)。要告诉司机它还需要BsonDiscriminator
:
[BsonDiscriminator(RootClass = true)]
[BsonKnownTypes(typeof(ConcreteTask))]
public class TaskBase
{
}
BsonClassMap.RegisterClassMap<TaskBase>();
BsonClassMap.RegisterClassMap<ConcreteTask>();
结果,文档的类型鉴别符(_t)将是一个数组,而不是单个值。在这种情况下:
{ _t : ["TaskBase", "ConcreteTask"] }
答案 1 :(得分:0)
晚了一点,按照i3arnon的回答,如果您想向驾驶员显示您的类层次结构而又不向类中添加属性,则可以按照这种方式遵循BsonClassMap选项
BsonClassMap.RegisterClassMap<TaskBase>(cm =>
{
cm.AutoMap();
cm.SetIsRootClass(true);
});
BsonClassMap.RegisterClassMap<ConcreteTask>(cm =>
{
cm.AutoMap();
});
并得到相同的结果: {_t:[“ TaskBase”,“ ConcreteTask”]}