3

我正在使用 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 对象时,它会抛出一个异常,指出在 Things 中使用了 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 作为 Detail 类型,一切正常。

我做错了吗?或者这在 CSharpDriver 的未来版本中是否可行?

4

1 回答 1

2

[澄清]

重读您的问题和评论,我意识到我错误地解决了您的问题。您对 new 关键字的使用不是非法的 - 编译器将允许您在派生类中返回具有相同名称的属性的不同类型 - 发生的情况是您告诉编译器派生类的 Details 属性独立于它的父类。

当你这样做时,通常表明你的类层次结构没有经过深思熟虑,这就是为什么我在最初的帖子中如此教条。

在您的情况下(尝试Details在 MongoDb 中存储具有不同的通用类)具有多态类层次结构,您正在与 MongoDb 驱动程序的序列化自动映射发生冲突。为了做你想做的事,你应该使用 MongoDb文档中描述的显式注册你的类的映射。引用文档的相关部分:

[来源:MongoDb 文档]

您必须自己调用 RegisterClassMap 的一种情况(即使没有参数)是当您使用多态类层次结构时:在这种情况下,您必须注册所有已知的子类以保证鉴别器被注册。

于 2013-09-05T06:42:09.537 回答