【问题标题】:how to manage _id field when using POCO with mongodb c# driver将POCO与mongodb c#驱动程序一起使用时如何管理_id字段
【发布时间】: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 属性,它不起作用。

【问题讨论】:

    标签: c# mongodb poco


    【解决方案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; }
        
                (...)
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2012-12-09
          • 2018-01-13
          • 2015-04-16
          • 2021-12-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-04-05
          • 2018-01-28
          相关资源
          最近更新 更多