gpt4 book ai didi

mongodb - 使用 Mongo C# 驱动程序持久化派生对象

转载 作者:IT老高 更新时间:2023-10-28 13:35:44 24 4
gpt4 key购买 nike

我有以下类层次结构

[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 属性未保存到数据库中,因为它还没有 setter 。序列化器不会序列化没有 setter 的属性(因为如果序列化器序列化此类属性,它将无法反序列化它)。因此,如果您想序列化 Name 属性,则只需添加假 setter(到 ICommand 中也需要添加它):

  public override string Name
{
get { return "Move Command"; }
set{}
}

2.如果您不想使用 BsonKnownTypes 属性,还有另一种方法可以通知序列化程序在反序列化期间可能遇到的已知类型。只需在应用启动事件上注册一次 map :

BsonClassMap.RegisterClassMap<MoveCommand>();
//all other inherited from ICommand classes need register here also

所以你应该为每个多态类使用或KnownTypes属性或注册BsonClassMap,否则在反序列化过程中会出现'unknown descriminator'错误:

  var commands = col.FindAllAs<ICommand>().ToList();

3 你说:

This is bad OO design and is being forced on my class hierarchy by the BSON library.

以任何方式,即使没有 KnownTypes 也可以通过 BsonId 属性使用 Bson lib 为您的代码赋予属性。如果你想避免它,你可以:

   BsonClassMap.RegisterClassMap<MoveCommand>(cm => {
cm.AutoMap();
cm.SetIdMember(cm.GetMemberMap(c => c.Id));
});

所以现在您可以从您的域代码库中删除对 Mongodb.Bson 库的引用。

关于mongodb - 使用 Mongo C# 驱动程序持久化派生对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6320035/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com