Reputation: 67
I have the structure below in C# (a customer with invoices). I'm struggling to insert into an existing mongodb record. I'm using C# .NET 4.5 together with MongoDB 2.4. I would like to insert a new invoice into an existing customer record.
I receive the error "duplicate key error" which I understand but I don't know how to append to the Invoices object within the Customer object.
Any help much appreciated.
My attempt
var client = new MongoClient();
var database = client.GetDatabase("databasename");
var collection = database.GetCollection<Customer>("Customer");
var customerId = "..";
var builder = Builders<Customer>.Filter;
var filter = builder.Eq("Id", new ObjectId(customerId));
var matchedRecord = collection.Find(filter).SingleOrDefault();
// Insert new invoice into the customer record
matchedRecord.Invoices.Add(new Invoice {
InvoiceNumber = "123456"
});
collection.InsertOne(matchedRecord); // Error produced below
Error
E11000 duplicate key error collection: databasename.Customer index: _id_ dup key: { : ObjectId('..') }
Classes
public class Customer
{
public ObjectId Id { get; set; }
public string CustomerId { get; set; }
public List<Invoice> Invoices { get; set; }
}
public class Invoice
{
public string InvoiceNumber { get; set; }
}
Update
var builder = Builders<Customer>.Filter;
var filter = builder.Eq("Id", new ObjectId(customerId));
// Not sure how to use the FindOneAndUpdate method(?)
var matchedRecord = collection.FindOneAndUpdate<Customer>(filter);
Second update
I've tried the following but it inserts a new invoice object (outside Invoices)
var builder = Builders<Customer>.Filter;
var filter = builder.Eq("Id", new ObjectId(customerId));
var update = Builders<Customer>.Update.Set("Invoice.ClientName", "HELLO");
Third update
This approach overwrites the customer's existing invoices and replaces it with this "hello" invoice. How can you append to the existing invoices..?
var update = Builders<Customer>.Update
.Set("Invoices", new Invoice
{
ClientName = "HELLO"
});
var result = collection.UpdateOneAsync(filter, update);
Upvotes: 1
Views: 2026
Reputation: 67
This works, notice the use of Push - otherwise it's the same as the set approach above (see third update)
var update = Builders<Customer>.Update.Push("Invoices", new Invoice
{
ClientName = "HELLO"
});
var result = collection.UpdateOneAsync(filter, update);
Upvotes: 2