使用 Mongo C# 驱动程序保留派生对象
我将得到以下类层次结构
[BsonKnownTypes(typeof(MoveCommand))]
public abstract class Command : ICommand
{
public abstract string Name
{
get;
}
public abstract ICommandResult Execute();
}
public class MoveCommand : Command
{
public MoveCommand()
{
this.Id = ObjectId.GenerateNewId().ToString();
}
[BsonId]
public string Id { get; set; }
public override string Name
{
get { return "Move Command"; }
}
public override ICommandResult Execute()
{
return new CommandResult { Status = ExecutionStatus.InProgress };
}
}
如果我像这样保存命令,
Command c = new MoveCommand();
MongoDataBaseInstance.GetCollection<Command>("Commands").Save(c);
:然后查询数据库,我看不到派生属性仍然存在。
{ "_id" : "4df43312c4c2ac12a8f987e4", "_t" : "MoveCommand" }
我希望 Name 属性作为文档中的键。 我做错了什么?
另外,有没有办法避免在基类上使用 BsonKnowTypes 属性来持久保存派生实例?我不明白为什么基类需要了解派生类。这是糟糕的 OO 设计,并且 BSON 库强加在我的类层次结构上。我在这里错过了什么吗?
I have the following class hierarchy
[BsonKnownTypes(typeof(MoveCommand))]
public abstract class Command : ICommand
{
public abstract string Name
{
get;
}
public abstract ICommandResult Execute();
}
public class MoveCommand : Command
{
public MoveCommand()
{
this.Id = ObjectId.GenerateNewId().ToString();
}
[BsonId]
public string Id { get; set; }
public override string Name
{
get { return "Move Command"; }
}
public override ICommandResult Execute()
{
return new CommandResult { Status = ExecutionStatus.InProgress };
}
}
if I save the command like so:
Command c = new MoveCommand();
MongoDataBaseInstance.GetCollection<Command>("Commands").Save(c);
and then query the DB, I don't see the derived properties persisted.
{ "_id" : "4df43312c4c2ac12a8f987e4", "_t" : "MoveCommand" }
I would expect a Name property as a key in the document.
What am I doing wrong?
Also, is there a way to avoid having a BsonKnowTypes attribute on the base class for persisting derived instances? I don't see the why a base class needs to know about derived classes. This is bad OO design and is being forced on my class hierarchy by the BSON library. Am I missing something here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
1.
Name
属性没有保存到数据库中,因为它没有setter。序列化程序不会序列化没有设置器的属性(因为如果序列化程序序列化此类属性,它将无法将其反序列化回来)。因此,如果你想序列化Name
属性,那么只需添加假设置器(到ICommand
中也需要添加它):2.如果你不想使用 BsonKnownTypes 属性,还有另一个通知序列化程序在反序列化过程中可能遇到的已知类型的方法。只需在应用程序启动事件上注册一次映射:
因此您应该使用或
KnownTypes
属性或为每个多态类注册 BsonClassMap
,否则您将在反序列化期间收到“未知鉴别器”错误:3 你说:
即使没有
KnownTypes
,也可以通过BsonId
属性使用 Bson lib 来分配代码。如果您想避免它,您可以:
现在您可以从域代码库中删除对
Mongodb.Bson
lib 的引用。1.
Name
property was not saved into database because it haven't setter. Serializers not serialize properties that's haven't setters (because if serializer serialize such property it will not able deserialize it back). So if you want serializeName
property then just add fake setter(intoICommand
need to add it also):2.If you don't want use BsonKnownTypes attribute there is another way to notify serializer about know types it might encounter during deserialization. Just Register maps once, on app start event:
So you should use or
KnownTypes
attribute or registerBsonClassMap
for each polymorphic class, otherwise you will get 'unknown descriminator' error during deserializtion:3 You said:
In any way even without
KnownTypes
atribute your code using Bson lib throughBsonId
attribute.If you want avoid it you can:
So now you can remove reference to
Mongodb.Bson
lib from your domain code lib.