0

I'm developing a 3-tier WinForms application. But when I try to add a new object to the database, some objects get duplicated.

Classes:

class Customer 
{
    public int Id { get; set; }
    public int CustomerName { get; set; }

    public virtual IList<CustomerAccount> CustomerAccount { get; set; }
}

class CustomerAccount
{
    public int Id { get; set; }
    public int CustomerId { get; set; }
    public int AccountId { get; set; }

    public virtual Customer Customer { get; set; }
    public virtual Account Account { get; set; }
}

class Account
{
    public int Id { get; set; }
    public int AccountName { get; set; }
}

This is the code I use to add the Customer object to the database:

 DataContext.CustomerSet.Add(customer);
 DataContext.SaveChanges();

The accounts that are added to the customer are existing accounts. And these are the rows that are duplicated in the database. So for example:

Customer c;
c.CustomerName = "Kevin";

c.CustomerAccount.Add(new CustomerAccount() {
    AccountId = existingAccountId,
    Account = existingAccount
}

AddCustomer(c);

In this example, existingAccount gets duplicated.

I know it's something with the DataContext.Attach() method. But that doesn't work when there is more than one CustomerAccount relation added. (An object with the same key already exists in the ObjectStateManager.)

Thanx in advance.

5
  • Only set existingAccountId. Commented Oct 24, 2014 at 18:01
  • How do I get the properties of the Account then? I use the Customer/Account properties for navigation purposes. Commented Oct 27, 2014 at 12:02
  • Oh, you can hang on to the Account property, but you don't have to set both. When you fetch Customer from the database you can access their CustomerAccount.Account and the Account data will be available. Commented Oct 27, 2014 at 12:11
  • Thx, this fixes the problem when attaching a detached entity. The only problem I now have is: because everything is detached, the navigation property is not working. Anyway to make that work? It only works when fetching existing record. Commented Oct 27, 2014 at 12:33
  • 1
    In that case you should attach the Account to the context the Customer is attached to and set CustomerAccount.Account after all. (In which case you don't have to set AccountId). Commented Oct 27, 2014 at 12:43

1 Answer 1

1

Don't create a new instance of CustomerAccount. you must reload it from your database and work with the object from the Context.

    Customer c;
    c.CustomerName = "Kevin";

    var customerAccount = DataContext.CustomerAccount.First( c => c.AccountId == existingAccountId)


    c.CustomerAccount = customerAccount;
    DataContext.Customer.Add(c);
    DataContext.SaveChanges();
Sign up to request clarification or add additional context in comments.

1 Comment

The CustomerAccount object is a relation. So fetching an existing one, makes no sense. Only the Account objects exist in the database. The relation between Customer and Account has yet to be defined by adding it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.