将POCO与mongodb c#驱动程序一起使用时如何管理_id字段
Posted
技术标签:
【中文标题】将POCO与mongodb c#驱动程序一起使用时如何管理_id字段【英文标题】:how to manage _id field when using POCO with mongodb c# driver 【发布时间】:2011-08-29 03:00:25 【问题描述】:如果我想用 POCO 读写 mongo 数据
public class Thingy
public string Foo get;set;
...
coll.Insert(new Thing(Foo = "hello"));
当我回读时,我收到一个失败消息,说 _id 是一个意外属性(确实如此)。因此,我在类中添加了一个名为 _id 的字段。现在插入不起作用,说 _id 字段不能为空。一个尝试过的 BsonIgnoreIfNull 属性,它不起作用。
【问题讨论】:
【参考方案1】:如下添加属性:
public BsonObjectId Id get; set;
MongoDB 驱动程序在序列化\反序列化过程中自动将Id
转换为_id
。
【讨论】:
thx - 我感觉有一组文档、示例或我缺少的东西:-) @Bryan Migliorisi - 这不起作用。插入(或保存)失败告诉我 Id 不能为空 @Bryan Migliorisi - 来自 mongodb git 站点的官方 c# 驱动程序,昨天下载 Id属性的数据类型应该是ObjectId,而不是BsonObjectId。虽然 BsonObjectId 看起来也很合理,所以我也会创建 JIRA 请求来支持它。 有趣...罗伯特,我已经为代码中的每个实体使用了 BsonObjectId,使用您的驱动程序没有任何问题。【参考方案2】:当您插入一个对象时,如果它没有 _id
字段,则驱动程序会添加一个并将其设置为 12 字节的 MongoDB ObjectId 值。
您只需将Id
属性添加到您的POCO,它将从_id
反序列化:
public class Thingy
public ObjectId Id get; set;
或者,如果您想委托另一个属性映射到_id
,那么您可以使用BsonIdAttribute
来装饰它,如下所示:
[BsonId]
public ObjectId MyKey get; set;
_id
字段不必是 MongoDB ObjectId
,您可以将其设置为任何数据类型(数组除外)的任何值,它只需要在集合中是唯一的即可。
【讨论】:
+1 最终解释 _id 可以设置为任何数据类型的任何值(数组除外)。关于这一点的官方文档让我有点困惑 [explitive] [explitive] [explitive],已经为此奋斗了 2 天。感谢@Chris Fulstow,这是一个不起眼但很关键的功能! 强调_id 字段不必是 MongoDB ObjectId。如果您使用 ObjectId 或 Bson 属性,那么您的对象不再是 POCO(普通的旧 CLR 对象),这就是答案。尽可能避免使用它们。 @ChadHedgcock 我跟着你。但是,如果我的 poco 类上没有与此相对应的任何属性,则在加载文档时会出现错误。比如“_id 不能映射到任何东西” @Jepzen 有点晚了,但类属性 [BsonIgnoreExtraElements] 可能会解决这个问题。【参考方案3】:您必须为 id 添加一个属性(或字段)并告诉序列化程序您要使用哪个 id 生成器。
[BsonId(IdGenerator = typeof(ObjectIdGenerator))]
public object ThingyId get; set;
MongoDb 驱动程序中有 3 个可用,您也可以自己编写。更多信息http://www.mongodb.org/display/DOCS/CSharp+Driver+Serialization+Tutorial#CSharpDriverSerializationTutorial-WriteacustomIdgenerator
【讨论】:
那个链接现在好像坏了。【参考方案4】:public class Thingy
public ObjectId Id get; set;
public string Foo get; set;
按类别
如果需要,请使用以下代码:
var collection = database.GetCollection<Thingy>("db_Thingy");
Thingy tg= new Thingy();
tg.Foo = "Hello";
collection.insert(tg);
【讨论】:
【参考方案5】:我一般都把Thingy包起来:
public class MongoThingy
public ObjectId Id get; set;
public Thingy Thingy get; set;
这让它变得容易多了,因为很多时候,Thingy 类来自另一个我无法控制的库。反序列化也更容易,以便将其交给其他人进行处理。
【讨论】:
【参考方案6】:https://docs.microsoft.com/pt-br/aspnet/core/tutorials/first-mongo-app?view=aspnetcore-5.0&tabs=visual-studio的路
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
namespace BooksApi.Models
public class Book
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id get; set;
[BsonElement("Name")]
public string BookName get; set;
(...)
【讨论】:
以上是关于将POCO与mongodb c#驱动程序一起使用时如何管理_id字段的主要内容,如果未能解决你的问题,请参考以下文章