首页 > 解决方案 > MongoDB:具有覆盖 ID 和属性的子类出现问题

问题描述

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

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

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的特定子数据模型。这需要我按照这个答案Id注释被覆盖的属性:[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
}

但不幸的是,它导致了这个错误:

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

我已经尝试注册类映射,RootClass = true在基本模型上添加类型鉴别器,以及在具有特殊[BsonKnownTypes(typeof(ChildDataModel), ...)]属性的基类上定义我的子数据模型,但无济于事。

我在这里做错了什么?

标签: c#.netmongodbmongodb-.net-drivermongodb-csharp-2.0

解决方案


按照惯例,MongoDB 驱动程序尝试将所有命名的属性映射Id_id类映射中。由于您有两个课程,因此它会注册_id两次。BsonIgnoreIfDefault如果是的话,更重要的Id是,null但这里不是,因为驱动程序会在您插入新文档时自动生成该值。

BsonIgnore如果您想_id在 MongoDB 中使用单曲,可以使用该问题的修复

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")
}

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


推荐阅读