使用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库将其强加给了我的类层次结构。我在这里想念什么吗?     

解决方法

        1.
Name
属性未设置,因此未保存到数据库中。序列化程序不会序列化没有设置程序的属性(因为如果序列化程序对此类属性进行序列化,它将无法反序列化该属性)。因此,如果要序列化
Name
属性,则只需添加伪造的setter(在
ICommand
中也需要添加它):
  public override string Name
  {
    get { return \"Move Command\"; }
    set{}
  }
2.如果您不想使用BsonKnownTypes属性,则可以通过另一种方式通知序列化程序有关反序列化期间可能遇到的已知类型。在应用启动事件中只需注册一次地图:
BsonClassMap.RegisterClassMap<MoveCommand>();
//all other inherited from ICommand classes need register here also
因此,您应为每个多态类使用或
KnownTypes
属性或注册ѭ8,,否则在反序列化期间会出现“未知描述符”错误:
  var commands = col.FindAllAs<ICommand>().ToList();
3您说:   这是糟糕的OO设计,正在   强迫我的班级等级   BSON库。 即使没有
KnownTypes
,也可以通过
BsonId
属性使用Bson lib来以任何方式分配代码。 如果要避免它,可以:
   BsonClassMap.RegisterClassMap<MoveCommand>(cm => {
        cm.AutoMap();
        cm.SetIdMember(cm.GetMemberMap(c => c.Id));
    });
因此,现在您可以从域代码库中删除对
Mongodb.Bson
库的引用。