MongoDB:子类有覆盖ID和属性的问题

时间:2019-04-16 15:46:44

标签: c# .net mongodb mongodb-.net-driver mongodb-csharp-2.0

在MongoDB存储设置的派生类中覆盖Id属性时,我遇到了很大的问题。

我所有数据模型都继承的基类如下:

public abstract class DataModel
{
     [BsonId]
     [BsonRepresentation(BsonType.ObjectId)]
     public virtual string Id { get; set; }

     public DateTime Created { get; set; }

     public DateTime Modified { get; set; }

     public DateTime Deleted { get; set; }
}

然后有一些使用 upserts 的特殊子数据模型。这要求我按照this answerId注释覆盖的[BsonIgnoreIfDefault]属性:

public class ChildDataModel : DataModel
{
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    [BsonIgnoreIfDefault]          //  <---- need this for Upserts to work
    public override string Id { get; set; }

    ... // child-specific properties
}

但不幸的是,它导致此错误:

  

类型的属性“ Id”   'Namespace.ChildDataModel'不能   使用元素名称“ _id”,因为属性已使用它   类型'Namespace.DataModel'的'Id'。

我尝试注册类映射,在基本模型上添加带有RootClass = true的类型鉴别符,并在基类上使用特殊的[BsonKnownTypes(typeof(ChildDataModel), ...)]属性定义子数据模型,但是无济于事。

我在这里做什么错了?

1 个答案:

答案 0 :(得分:2)

按惯例,MongoDB驱动程序尝试将所有名为Id的属性映射到类映射中的_id中。由于有两个类,因此它将_id注册两次。更重要的是,如果BsonIgnoreIfDefaultIdnull可以很好地工作,但是这里不是,因为插入新文档时驱动程序会自动生成值。

要解决此问题,如果您想在MongoDB中使用单个BsonIgnore,可以使用_id

public class ChildDataModel : DataModel
{        
    [BsonRepresentation(BsonType.ObjectId)]
    [BsonIgnore]
    public override string Id { get; set; }
}

将存储为:

{
    "_id" : ObjectId("5cb5fe72e2a22b3848b6a1f6"),
    "Created" : ISODate("2019-04-16T16:10:25.908Z"),
    "Modified" : ISODate("2019-04-16T16:10:25.914Z"),
    "Deleted" : ISODate("2019-04-16T16:10:25.914Z")
}

或者,如果您要分别存储两个值,则可以使用BsonNoId属性:

[BsonNoId]
public class ChildDataModel : DataModel
{        
    [BsonRepresentation(BsonType.ObjectId)]
    public override string Id { get; set; }
}

将是:

{
    "_id" : ObjectId("5cb5fecde2a22b3088ef731c"),
    "Created" : ISODate("2019-04-16T16:11:56.810Z"),
    "Modified" : ISODate("2019-04-16T16:11:56.822Z"),
    "Deleted" : ISODate("2019-04-16T16:11:56.822Z"),
    "Id" : ObjectId("5cb5fecde2a22b3088ef731c")
}

但是从应用程序角度来看它仍然是相同的值