在他们提到upserts的MongoDB的官方文档,所以这将是非常好的写UPSERT命令代替:Upserting在蒙戈DB使用官方的C#驱动
if (_campaignRepo.Exists(camp))
{
_campaignRepo.DeleteByIdAndSystemId(camp);
}
_campaignRepo.Save(camp);
一些东西,将实施对这一逻辑数据库级别,如果可能的话。那么如果有的话,做什么方法可以做什么?
在他们提到upserts的MongoDB的官方文档,所以这将是非常好的写UPSERT命令代替:Upserting在蒙戈DB使用官方的C#驱动
if (_campaignRepo.Exists(camp))
{
_campaignRepo.DeleteByIdAndSystemId(camp);
}
_campaignRepo.Save(camp);
一些东西,将实施对这一逻辑数据库级别,如果可能的话。那么如果有的话,做什么方法可以做什么?
下面的代码是从工作程序:
weekplanStore.Update(
Query.EQ("weekNumber", week),
Update.Replace(rawWeekPlan),
UpdateFlags.Upsert);
的weekplanStore是我的MongoDB的集合,该代码将更新文档中与查询中的第一个参数或如果没有找到,则插入一个新的。 “技巧”是使用UpdateFlags.Upsert修饰符。
的rawWeekPlan是插入或更新的对象,并具有以下类型:
private class RawWeekPlan
{
public ObjectId id;
public int weekNumber;
public WeekPlanEntry[] entries;
}
和由驾驶员自动地变成BSON。
版本2的MongoDB C#驱动程序需要在写入命令中设置IsUpsert
标志。本示例将插入整个文档。
var newDoc = new BsonDocument { { "_id", 123 }, { "someKey", "someValue" } };
var result = await collection.ReplaceOneAsync(
filter: new BsonDocument("_id", 123),
options: new UpdateOptions { IsUpsert = true }
replacement: newDoc);
版MongoDB的C#驱动器的1实现Save
命令内此逻辑。
var newDoc = new BsonDocument { { "_id", 123 }, { "someKey", "someValue" } };
collection.Save(newDoc);
的保存方法是插入和更新的组合。如果文档的Id成员有一个值,则假定它是现有文档并在文档上保存调用Update(设置Upsert标志,以防万一它实际上是新文档)。否则,在首先将新生成的唯一值分配给Id成员后,假定它是新文档并保存调用Insert。
参考:http://mongodb.github.io/mongo-csharp-driver/1.11/driver/#save-tdocument-method
注:这确实需要但ID字段的正确映射。在这里更多信息:http://mongodb.github.io/mongo-csharp-driver/1.11/serialization/#identifying-the-id-field-or-property
这对于新的API不再可行。 –
已更新。尽管我认为新的API使得upsert命令更难使用。 –
如果newDocs ID为null,即它是插入,那么传递给过滤器的是什么?只是一个空的BBS文件? – BenCr
您可以使用常规的更新命令,但只是通过它的Upsert更新标志
MongoCollection collection = db.GetCollection("matches");
var query = new QueryDocument("recordId", recordId);
var update = Update.Set("FirstName", "John").Set("LastName","Doe");
matchCollection.Update(query, update, UpdateFlags.Upsert, SafeMode.False);
该代码是从工作的应用程序(简称为清楚起见)
从V2.0开始适应驱动程序有一个新的异步API。不应该再使用旧的API,因为它是新API的屏蔽外观,因此不推荐使用。
目前推荐的方法来更新插入的文件是通过调用并等待ReplaceOneAsync
与IsUpsert
标志开启,并且有关文件相匹配的过滤器:
Hamster hamster = ...
var replaceOneResult = await collection.ReplaceOneAsync(
doc => doc.Id == hamster.Id,
hamster,
new UpdateOptions {IsUpsert = true});
您可以检查操作是否插入或通过查看ReplaceOneResult.MatchedCount
进行更新:
我想使用ReplaceOneAsync,但它会引发异常:“元素名称”无效“,我正在使用updateOneasync的过滤器,但它的工作原理与replaceone不同。你能帮我么? –
它适用于嵌套集合吗?你试过了吗?因为它不适合他们在我的情况下 –
不知道。我没有尝试过嵌套集合。 –
问题出在id-s。我问了另一个线程上的问题 –