0
votes

Problem (see AbandonOrderTest3 in code below):

A customer object and a order object are newed up.

The customer is set as a property of the order.

The order is attached to a context however SaveChanges is not called.

The context is disposed.

An order object is newed up again, and the customer object is set as a property.

A new context is created and the order is added. SaveChanges is called.

The order is added twice to the database (this is the problem, it should be added once).

.Net version: 4.5, EF version: 6.1.3

    public void AbandonOrderTest1()
    {
        // Works as expected
        Customer c1 = new Customer { Name = "C1", ID = 9 };  // Customer with this ID already exists
        Order order = new Order { Customer = c1, CustomerID = c1.ID };

        using (Repository.db db = new Repository.db(_connectionString))
        {
            db.Orders.Add(order);
            db.Entry(order.Customer).State = EntityState.Detached;
            db.SaveChanges();
        }
    }

    public void AbandonOrderTest2()
    {
        // Order is added once, customer is added again as expected
        Customer c1 = new Customer { Name = "C1", ID = 9 };  // Customer with this ID already exists
        Order order = new Order { Customer = c1, CustomerID = c1.ID };

        using (Repository.db db = new Repository.db(_connectionString))
        {
            db.Orders.Add(order);
            // Save changes is not called here
        }

        // db is disposed at this point.  Neither order nor c1 should be 
        // attached to any context as no context exists for them to be 
        // attached to.


        using (Repository.db db = new Repository.db(_connectionString))
        {
            db.Orders.Add(order);
            db.SaveChanges();
        }
    }

    public void AbandonOrderTest3()
    {
        // Order is added twice, customer is added again as expected
        Customer c1 = new Customer { Name = "C1", ID = 9 };  // Customer with this ID already exists
        Order order = new Order { Customer = c1, CustomerID = c1.ID };

        using (Repository.db db = new Repository.db(_connectionString))
        {
            db.Orders.Add(order);
            // Save changes is not called here
        }

        // db is disposed at this point.  Neither order nor c1 should be 
        // attached to any context as no context exists for them to be 
        // attached to.

        // --- New up the order again 
        order = new Order { Customer = c1, CustomerID = c1.ID };  

        using (Repository.db db = new Repository.db(_connectionString))
        {
            var orderState = db.Entry(order).State;         // Detached
            var custState = db.Entry(order.Customer).State; // Detached
            db.Orders.Add(order);
            db.SaveChanges();
        }
    }
2

2 Answers

0
votes

I have written an article about this issue: Entity Framework - Entity Added twice in Database

In fact, the order has not been added twice. The first order created has been added then the second order created has been added in the database.

var customer = new Association_OneToMany_Left();
var order1 = new Association_OneToMany_Right();
var order2 = new Association_OneToMany_Right();

order1.Left = customer;
order2.Left = customer;

using (var ctx = new TestContext())
{
    // Adding the first order create a new order list in the customer entity
    // customer.Right (The order list) contains now one element, the order1
    ctx.Association_OneToMany_Rights.Add(order1);

    // DO NOT save in the database.
}

using (var ctx = new TestContext())
{
    // customer.Right contains now two elements (order1 previously added and order2)
    ctx.Association_OneToMany_Rights.Add(order2);

    // Save left, order1 added from previous context and order2 added in this context
    ctx.SaveChanges();
}
-1
votes
using (Repository.db db = new Repository.db(_connectionString))
        {
            db.Orders.Add(order);
            // Save changes is not called here
        }

you must add..

using (Repository.db db = new Repository.db(_connectionString))
            {
                db.Orders.Add(order);
                <php? cout << db.Orders.Add ?!>

            }