2

I'm adding an UpdateCustomer method that passes in the modified customer to be persisted to the DB. But I've come across an error when calling ReplaceOneAsync on the updated document.

I've consulted the following example and api reference, which both state to pass ReplaceOneAsync a filter and document parameters.

But the specific errors are thrown because of incorrect parameters, as stated below:

Error   1   The best overloaded method match for 'MongoDB.Driver.IMongoCollection<MongoDBApp.Models.CustomerModel>.ReplaceOneAsync(MongoDB.Driver.FilterDefinition<MongoDBApp.Models.CustomerModel>, MongoDBApp.Models.CustomerModel, MongoDB.Driver.UpdateOptions, System.Threading.CancellationToken)' has some invalid arguments 

Error   2   Argument 2: cannot convert from 'MongoDB.Bson.BsonDocument' to 'MongoDBApp.Models.CustomerModel'    

Anyone have any hints on making sense of the error?

The UpdateCustomer method:

public async Task UpdateCustomer(CustomerModel customer)
{          
    var collection = StartConnection();
    var filter = Builders<CustomerModel>.Filter.Where(x => x.Id == customer.Id);

    BsonDocument doc = new BsonDocument();

    doc["_id"] = customer.Id;
    doc["firstName"] = customer.FirstName;
    doc["lastName"] = customer.LastName;
    doc["email"] = customer.Email;

    //error thrown here on the ReplaceOneAsync params..
    await collection.ReplaceOneAsync(filter, doc);           
}

And the associated StartConnection method:

private static IMongoCollection<CustomerModel> StartConnection()
{
    var client = new MongoClient(connectionString);
    var database = client.GetDatabase("orders");
    //Get a handle on the customers collection:
    var collection = database.GetCollection<CustomerModel>("customers");
    return collection;
}
i3arnon
  • 113,022
  • 33
  • 324
  • 344
Brian Var
  • 6,029
  • 25
  • 114
  • 212

2 Answers2

2

You need to use the typed collection all the way down which means inserting an instance of CustomerModel, not a BsonDocument:

await collection.ReplaceOneAsync(filter, customer);

Or use the untyped one with BsonDocument, but do that from the start:

var collection = database.GetCollection<BsonDocument>("customers");

You're getting these compiliation errors because you're mixing these two options.

i3arnon
  • 113,022
  • 33
  • 324
  • 344
  • Ok so that fixed the incorrect params error, but when I step through that method the value isn't updated on the remote database. Not sure why as the method returns, and the filter and customer are correct when contents are checked. Also it's not a connection issue as my database contents are loading, when I refresh my data grid..Any ideas how to debug that further? – Brian Var Nov 23 '15 at 22:16
  • @BrianJ ReplaceOneAsync actually has a result. You can look at it and see whether any of the documents were affected and how. – i3arnon Nov 23 '15 at 22:49
  • I added a result var in order to check the contents of ReplaceOneAsync after execution, like this: ` var result = await collection.ReplaceOneAsync(filter, customer);` Not quite sure how to decipher the details when I stepped into it, picture linked here: http://picpaste.com/pics/result_debug-9QyUE5QF.1448319996.PNG Can you advise? – Brian Var Nov 23 '15 at 23:09
  • @BrianJ There isn't a matching document in the db. You need to use the `IsUpsert` flag: http://stackoverflow.com/a/30265529/885318 – i3arnon Nov 23 '15 at 23:25
  • Okay that was the solution, it didn't have the expected outcome though..A new document was added to the DB and the original document is still present. I was expecting the original to be deleted or overwritten. Is there something I'm missing there? @i3arnon – Brian Var Nov 23 '15 at 23:32
  • @BrianJ The filter doesn't match the existing document. In your image you can see that `MatchedCount == 0`. – i3arnon Nov 23 '15 at 23:37
  • ok I see the matched count now in the result, not sure why that would be? The filter checks that: Filter.Where(x => x.Id == customer.Id) And the customer id from the selectedCustomer in my app and on the remote DB are the same. @i3arnon – Brian Var Nov 23 '15 at 23:46
  • I've linked a pic of the updated record and the original in the data grid, as you mentioned there was 0 mathcedcount, but in the image both records have the same id, any ideas where I could be wrong here? http://picpaste.com/pics/result_debug-mEWDvbnP.1448388065.PNG – Brian Var Nov 24 '15 at 18:02
1

this works for me

var filter = Builders.Filter.Where(x => x.Id == customer.Id); await Collection.ReplaceOneAsync(filter, item, new ReplaceOptions { IsUpsert = true });

D__
  • 141
  • 1
  • 5