1

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);
5
  • Insert is to create new doc. Use findAndUpdate or Update variants for updating existing documents. Commented Jan 21, 2017 at 14:13
  • I've updated my question, I'm not sure about how to use the findAndUpdate method. Commented Jan 21, 2017 at 14:22
  • can you provide an example please? Many thanks, Commented Jan 21, 2017 at 14:42
  • 2
    Use $push variant with your second update to add invoice to existing invoices. Sorry,I don't know C# Commented Jan 21, 2017 at 15:24
  • no problem, I have it working now in my answer, many thanks for your help Commented Jan 23, 2017 at 12:40

1 Answer 1

2

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);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.