How to wrap bulk upsert in Mongo with Task in C#
How to wrap bulk upsert in Mongo with Task in C#
I have some model
public partial class Option
{
[BsonId]
public int Id { get; set; }
public Quote Quote { get; set; }
public Contract Contract { get; set; }
}
Method that does bulk write
public Task SaveOptions(List<Option> contracts)
{
var context = new MongoContext();
var processes = new List<Task<UpdateResult>>();
var collection = context.Storage.GetCollection<Option>("options");
contracts.ForEach(contract =>
{
var item = Builders<Option>.Update.Set(o => o, contract);
var options = new UpdateOptions { IsUpsert = true };
processes.Add(collection.UpdateOneAsync(o => o.Id == contract.Id, item, options));
});
return Task.WhenAll(processes);
}
Call for the method above
Task.WhenAll(service.SaveOptions(contracts)) // also tried without Task.WhenAll
For some reason, it doesn't create any record in Mongo DB
Update
Tried to rewrite bulk write this way, still no changes.
public Task SaveOptions(List<Option> contracts)
{
var context = new MongoContext();
var records = new List<UpdateOneModel<Option>>();
var collection = context.Storage.GetCollection<Option>("options");
contracts.ForEach(contract =>
{
var record = new UpdateOneModel<Option>(
Builders<Option>.Filter.Where(o => o.Id == contract.Id),
Builders<Option>.Update.Set(o => o, contract))
{
IsUpsert = true
};
records.Add(record);
});
return collection.BulkWriteAsync(records);
}
UpdateOne
ReplaceOne
@john it works, add this as an answer and I will accept it
– Anonymous
Jul 2 at 4:50
even though, I thought that update and replace do the same thing, but update is more flexible because it allows to change structure of the record on update
– Anonymous
Jul 2 at 4:50
1 Answer
1
I think you want to use ReplaceOneAsync
:
ReplaceOneAsync
processes.Add(collection.ReplaceOneAsync(o => o.Id == contract.Id, contract, options));
The problem with using UpdateOneAsync
here is that you're supposed to specify a field to update, and o => o
doesn't do that. Since you want to replace the entire object, you need to use ReplaceOneAsync
.
UpdateOneAsync
o => o
ReplaceOneAsync
** Note that you can also do this with BulkWriteAsync
by creating a ReplaceOneModel
instead of an UpdateOneModel
.
BulkWriteAsync
ReplaceOneModel
UpdateOneModel
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Hint: You don't want
UpdateOne
, you wantReplaceOne
:)– john
Jul 2 at 4:22