我正在使用C#驱动程序使用MongoDB。 问题是,我想在MongoDB中存储不同类型的对象,包括一些常见字段和不同的详细信息字段。不同的客户端处理数据库中的不同类型。
代码如下所示:
class Things
{
public string Name {get;set;}
public string User { get; set; }
public ObjectId Id { get; set; }
public virtual Dictionary<string, object> Details { get; set; }
}
class Pc:Things
{
public new Detail Details { get; set; }
}
class Detail
{
public string cpu { get; set; }
public int ram { get; set; }
public int hdd { get; set; }
}
当我进行查询并尝试获取Pc对象时,它会抛出一个异常,说明在事物中使用了Details属性,因此它不能在Pc中使用。我想,在反序列化对象期间抛出了预期。
当我再上课时:
class Pc2
{
public string Name { get; set; }
public string User { get; set; }
public ObjectId Id { get; set; }
public Detail Details { get; set; }
}
与Thing相同,但使用Details as Detail类型,一切正常。
我这样做错了吗?或者这将在CSharpDriver的未来版本中实现吗?
答案 0 :(得分:1)
[澄清]
重读你的问题和评论我发现我错误地解决了你的问题。您对new关键字的使用并不违法 - 编译器将允许您使用具有相同名称的属性在派生类中返回不同类型 - 会发生的事情是您告诉编译器派生类'Details属性是从其父类中独立。
当你这样做时,通常表明你的班级等级没有经过深思熟虑,这就是为什么我在最初的帖子中如此教条化。
在你的情况下(尝试在MongoDb中存储具有不同Details
的公共类)具有多态类层次结构,你正在运行MongoDb驱动程序的序列化自动化。为了做你想做的事,你应该使用MongoDb documentation中描述的显式注册你的类映射。引用文档的相关部分:
[来源:MongoDb文档]
您必须自己调用RegisterClassMap的一种情况(即使没有参数)是在使用多态类层次结构时:在这种情况下,您必须注册所有已知的子类以保证鉴别器被注册。