Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Mongo DB中的升级和Id问题_C#_Mongodb_Mongodb .net Driver - Fatal编程技术网

C# Mongo DB中的升级和Id问题

C# Mongo DB中的升级和Id问题,c#,mongodb,mongodb-.net-driver,C#,Mongodb,Mongodb .net Driver,我在使用官方C#驱动程序升级到mongo db时遇到问题 公共抽象类聚合对象 { /// ///所有mongoDb文档都必须有一个id,我们在这里指定它 /// 受保护的AggregateRoot() { Id=ObjectId.GenerateNewId(); } [BsonId] 公共对象Id{get;set;} } 我的实体已经有了id-s,但我必须创建特定于mongo的id才能工作,因为集合中的所有文档都应该有一个id。现在,我在我的系统中接收到一个新的实体,生成了一个新的Mong

我在使用官方C#驱动程序升级到mongo db时遇到问题

公共抽象类聚合对象
{
/// 
///所有mongoDb文档都必须有一个id,我们在这里指定它
/// 
受保护的AggregateRoot()
{
Id=ObjectId.GenerateNewId();
}
[BsonId]
公共对象Id{get;set;}
}
我的实体已经有了id-s,但我必须创建特定于mongo的id才能工作,因为集合中的所有文档都应该有一个id。现在,我在我的系统中接收到一个新的实体,生成了一个新的Mongo Id,我得到了一个文件的Mongo cannot change\u Id旧的异常。附近有工作吗

让我描述一下设计。所有将成为 存储为文档是从AggregateRoot继承的,AggregateRoot具有 它的id生成。每个子文档都生成了其id 自动地,我对此没有问题。AggregateRoot中的id 用于更正从中检索数据时出现的问题 引入MongoCollection来列表和生成,因此id-s 它们是不同的。现在我们可以将id生成移动到保存方法 因为更新的新实体具有新的id生成。但是它 这意味着团队中的每个开发人员都不能忘记生成id-s 在有风险的存储库中。忽略id会更好 而不是从mongo映射,如果可能的话,也不需要 AggregateRoot类


看起来您可能正在为插入和更新显式设置
Id
值。这对于插入很好,所有新对象都需要
\u id
值,但是对于更新,在创建现有文档后,不允许更改其
\u id
的值


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

我遇到过类似的问题。 我想使用官方的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#中写道:

但它不起作用!因为驱动程序在update语句中包含空id,并且当我向上插入具有不同Field1值的第二个文档时,抛出异常
E11000重复键错误索引
(在这种情况下,Mongo尝试插入一个具有已存在于db中的_id的文档)

当我自己生成_id(如主题启动程序)时,我遇到了相同的异常(
mongo无法更改文档的_id
)对现有值为Field1的对象进行升级


解决方案是通过属性
[BsonIgnoreIfDefault]
标记Id属性(而不是初始化它)。在这种情况下,驱动程序在update语句中省略了_id字段,如果需要,MongoDb将生成id。

您如何保存对象?BsonId属性应该强制MongoDB使用该字段作为id。其思想是数据来自外部存储系统。它有自己的id,我必须保存。为了与Mongo兼容,这是一个假的id。每个文档都继承自AggregateRoot,因此在接收每个对象时都会生成这个东西。很明显,我可能会收到相同的数据,但生成的mongo id不同。因此,如果我删除id属性,那么保存/更新实体就不会有问题。问题是,当我试图从代码中搜索集合时,它会引发异常,因为它无法将_id映射到不存在的属性。如果集合中的字段没有匹配的属性,您可以在类上使用
[bsonignorextraelements]
属性。另外[BsonIgnoreIfDefault]必须在您的解决方案之外使用,正如@renadeen解释的那样,[BsonIgnoreIfDefault]节省了大量时间。很遗憾我可以投更多的票给你。我浪费了大约一个小时试图弄清楚为什么我用2.0驱动程序进行的ReplaceOneAsync调用不起作用。找到了这个答案。添加了[BsonIgnoreIfDefault]并解决了问题。谢谢我花了好几个小时想弄明白。谢谢这就是解决方案这里有一个很大的“问题”,如果你过滤_id:
只是重申一下,这不起作用,如果过滤器包含_id,那么服务器将始终使用该值作为新文档的_id,如果没有匹配的现有文档,并且ReplaceOne调用会导致upsert。即使筛选器中的_id的值为null(或空ObjectId),这也是正确的。
public class MyClass
{
    public ObjectId Id { get; set; }
    public int Field1 { get; set; }
    public string Field2 { get; set; }
}
collection.Update(Query.EQ("Field1", 3),
                Update.Replace(new MyClass { Field1 = 3, Field2 = "value" }),
                UpdateFlags.Upsert);