在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 answer用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
}
但不幸的是,它导致此错误:
类型的属性“ Id” 'Namespace.ChildDataModel'不能 使用元素名称“ _id”,因为属性已使用它 类型'Namespace.DataModel'的'Id'。
我尝试注册类映射,在基本模型上添加带有RootClass = true
的类型鉴别符,并在基类上使用特殊的[BsonKnownTypes(typeof(ChildDataModel), ...)]
属性定义子数据模型,但是无济于事。
我在这里做什么错了?
答案 0 :(得分:2)
按惯例,MongoDB驱动程序尝试将所有名为Id
的属性映射到类映射中的_id
中。由于有两个类,因此它将_id
注册两次。更重要的是,如果BsonIgnoreIfDefault
为Id
,null
可以很好地工作,但是这里不是,因为插入新文档时驱动程序会自动生成值。
要解决此问题,如果您想在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")
}
但是从应用程序角度来看它仍然是相同的值