插入Mongodb和Id问题

时间:2011-09-02 12:06:03

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

使用官方C#驱动程序向mongo db上传时遇到问题。

public abstract class AggregateRoot
{
    /// <summary>
    /// All mongoDb documents must have an id, we specify it here
    /// </summary>
    protected AggregateRoot()
    {
        Id = ObjectId.GenerateNewId();
    }

    [BsonId]
    public ObjectId Id { get; set; }
}

我的实体已经拥有了id-s但我必须创建mongo特定的ID才能工作,因为集合中的所有文档都应该有一个。现在,我在系统中收到一个新实体,生成一个新的Mongo Id,我得到 mongo无法更改文档旧异常的_id。有一些解决方法吗?

  

让我来描述一下设计。所有实体都是   存储为文件的是继承自AggregateRoot的   id生成在其中。每个子文档都生成了id   自动,我对此没有任何问题。 AggregateRoot中的id   在从中检索数据时引入以纠正问题   MongoCollection to List和生成引入了id-s   是不同的。现在我们可以移动id生成来保存方法   因为更新的新实体有一个新的id生成。但它   意味着团队中的每个开发者都不能忘记生成id-s   在存储库中存在风险。忽略id会更好   如果有可能而不是从mongo映射   所有

的AggregateRoot类

2 个答案:

答案 0 :(得分:62)

我遇到过类似的问题。 我想使用官方C#驱动程序来插入文档。我有一个这样的课:

public class MyClass
{
    public ObjectId Id { get; set; }
    public int Field1 { get; set; }
    public string Field2 { get; set; }
}

在控制台中我会写:db.collection.update({Field1: 3},{Field1: 3, Field2: "value"})它会起作用。在C#中我写道:

collection.Update(Query.EQ("Field1", 3),
                Update.Replace(new MyClass { Field1 = 3, Field2 = "value" }),
                UpdateFlags.Upsert);

它不起作用!因为驱动程序在update语句中包含空id,并且当我使用不同的Field1异常值E11000 duplicate key error index向上插入第二个文档时(在这种情况下,Mongo尝试插入带有已存在于db中的_id的文档)。

当我自己生成_id时(比如主题启动器),我在遇到具有现有值Field1的对象时遇到了相同的异常(mongo cannot change _id of a document)。

解决方案是按属性[BsonIgnoreIfDefault]标记Id属性(而不是初始化)。在这种情况下,驱动程序省略update语句中的_id字段,MongoDb在必要时生成Id。

答案 1 :(得分:8)

您可能会明确为插入和更新设置Id值。这对于插入来说很好,所有新对象都需要_id值,但是对于更新,您不能在创建现有文档后更改_id的值。

尝试根本不设置Id值。如果在插入之前未指定值,则驱动程序使用内置的IdGenerator类生成新的_id值,因此如果它是ObjectId类型,则它将使用ObjectIdGenerator。然后你的插入和更新都可以正常工作。