在mongodb的官方文档中,他们提到了upserts,因此编写upsert命令而不是:
if (_campaignRepo.Exists(camp)) { _campaignRepo.DeleteByIdAndSystemId(camp); } _campaignRepo.Save(camp);
如果可能的话,可以在数据库级别实现该逻辑的东西。那么,如果有的话,该怎么做呢?
在mongodb的官方文档中,他们提到了upsert,因此编写upsert命令来代替:if(_campaignRepo.Exists(camp)){_campaignRepo ....] [
weekplanStore.Update(
Query.EQ("weekNumber", week),
Update.Replace(rawWeekPlan),
UpdateFlags.Upsert);
rawWeekPlan是已插入或更新的对象,并且具有以下类型:
private class RawWeekPlan
{
public ObjectId id;
public int weekNumber;
public WeekPlanEntry[] entries;
}
并且由驱动程序自动变成bson。
MongoDB C#驱动程序的Version 2需要在写入命令中设置IsUpsert
标志。此示例将插入整个文档。MongoDB C#驱动程序的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);
版本1在
Save
命令中实现此逻辑。var newDoc = new BsonDocument { { "_id", 123 }, { "someKey", "someValue" } }; collection.Save(newDoc);
Save方法是Insert和Update的组合。如果文档的Id成员具有值,则假定它是现有文档,并且Save对该文档调用Update(仅将Upsert标志设置为如果它实际上毕竟是一个新文档)。否则,假定它是一个新文档,并且在将新生成的唯一值分配给ID成员后,Save调用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
从驱动程序的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
来检查操作是插入还是更新:
您可以使用常规更新命令,但只需向其传递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);
该代码是从正在运行的应用程序改编而成(为清楚起见,已缩短)