title: EF 4.1 Code First - duplicate entities in object graph causes exception
body: <p>I am getting the following exception when attempting to save my entity:</p>
  
  <p><em>"AcceptChanges cannot continue because the object's key values conflict with another     object in the ObjectStateManager. Make sure that the  key values are unique before calling AcceptChanges."</em></p>
  
  <p>I'm creating a 3 tiered application where the data access layer is using EF Code First, and where the client calls the middle tier using WCF.  I am therefore unable able to let the context track the entity state when building up an entity on the client.</p>
  
  <p>In some situations I am finding that the same entity is contained twice in the object graph.  In this situation it fails when I try and set the entity state of the duplicate.</p>
  
  <p>For example, I have the following entities:
  Customer
  Country
  Curreny</p>
  
  <ol>
  <li>From the client I create a new
  instance of a Customer. I then make
  a service call to get Country
  instance and assign it to the Customer. The Country instance has
  an associated Currency.</li>
  <li>The user can then associate a
  Currency with the customer.  They
  may well choose the same Currency
  that's associated with the Country.</li>
  <li>I make another service call to get
  this.  Thus at this stage we may
  have two separate instances of the
  same currency.</li>
  </ol>
  
  <p>So what I end up with are two instance of the same entity in the object graph.</p>
  
  <p>When then saving the entity (in my service) I need to tell EF that both Currency entities are not modified (if I don't do this I get duplicates).  Problem is that I get the exception above.</p>
  
  <p>On saving if I set the Currency instance on Country instance to null, it resolves the problem, but I feel like the code is becoming increasingly messy (due to this and other WCF related EF workarounds I'm having to put in place).</p>
  
  <p>Are there any suggestions on how to resolve this in a nicer way?</p>
  
  <p>Many thanks for any help in advance.  Here's the code:</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Data.Entity.ModelConfiguration;
  using System.ComponentModel.DataAnnotations;
  using System.Data.Entity;
  using System.Linq;
  
  namespace OneToManyWithDefault
  {
  
      public class Customer
      {
          public int Id { get; set; }
          public string Name { get; set; }
          public Country Country { get; set; }
          public Currency Currency { get; set; }
          public byte[] TimeStamp { get; set; }
      }
  
      public class Country
      {
          public int Id { get; set; }
          public string Name { get; set; }
          public Currency Currency { get; set; }
          public byte[] TimeStamp { get; set; }
      }
  
      public class Currency
      {
          public int Id { get; set; }
          public string Symbol { get; set; }
          public byte[] TimeStamp { get; set; }
      }
  
  
      public class MyContext
          : DbContext
      {
          public DbSet&lt;Customer&gt; Customers { get; set; }
          public DbSet&lt;Currency&gt; Currency { get; set; }
          public DbSet&lt;Country&gt; Country { get; set; }
  
          public MyContext(string connectionString)
              : base(connectionString)
          {
              Configuration.LazyLoadingEnabled = false;
              Configuration.ProxyCreationEnabled = false;
          }
  
          protected override void OnModelCreating(DbModelBuilder modelBuilder)
          {
              modelBuilder.Configurations.Add(new CustomerConfiguration());
              modelBuilder.Configurations.Add(new CountryConfiguration());
              modelBuilder.Configurations.Add(new CurrencyConfiguration());
              base.OnModelCreating(modelBuilder);
          }
      }
  
      public class CustomerConfiguration
          : EntityTypeConfiguration&lt;Customer&gt;
      {
          public CustomerConfiguration()
              : base()
          {
              HasKey(p =&gt; p.Id);
              Property(p =&gt; p.Id)
                  .HasColumnName("Id")
                  .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
                  .IsRequired();
              Property(p =&gt; p.TimeStamp)
                  .HasColumnName("TimeStamp")
                  .IsRowVersion();
  
              ToTable("Customers");
          }
      }
  
      public class CountryConfiguration
          : EntityTypeConfiguration&lt;Country&gt;
      {
          public CountryConfiguration()
              : base()
          {
              HasKey(p =&gt; p.Id);
              Property(p =&gt; p.Id)
                  .HasColumnName("Id")
                  .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
                  .IsRequired();
              Property(p =&gt; p.TimeStamp)
                  .HasColumnName("TimeStamp")
                  .IsRowVersion();
  
              ToTable("Countries");
          }
      }
  
      public class CurrencyConfiguration
          : EntityTypeConfiguration&lt;Currency&gt;
      {
          public CurrencyConfiguration()
              : base()
          {
              HasKey(p =&gt; p.Id);
              Property(p =&gt; p.Id)
                  .HasColumnName("Id")
                  .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
                  .IsRequired();
              Property(p =&gt; p.TimeStamp)
                  .HasColumnName("TimeStamp")
                  .IsRowVersion();
  
              ToTable("Currencies");
          }
      }
  
      class Program
      {
          private const string ConnectionString =
              @"Server=.\sql2005;Database=DuplicateEntities;integrated security=SSPI;";
  
          static void Main(string[] args)
          {
              // Seed the database
              MyContext context1 = new MyContext(ConnectionString);
  
              Currency currency = new Currency();
              currency.Symbol = "GBP";
              context1.Currency.Add(currency);
  
              Currency currency2 = new Currency();
              currency2.Symbol = "USD";
              context1.Currency.Add(currency2);
  
              Country country = new Country();
              country.Name = "UK";
              country.Currency = currency;
              context1.Country.Add(country);
  
              context1.SaveChanges();
  
              // Now add a new customer
              Customer customer = new Customer();
              customer.Name = "Customer1";
  
              // Assign a country to the customer
              // Create a new context (to simulate making service calls over WCF)
              MyContext context2 = new MyContext(ConnectionString);
              var countries = from c in context2.Country.Include(c =&gt; c.Currency) where c.Name == "UK" select c;
              customer.Country = countries.First();
  
              // Assign a currency to the customer
              // Again create a new context (to simulate making service calls over WCF)
              MyContext context3 = new MyContext(ConnectionString);
              customer.Currency = context3.Currency.First(e =&gt; e.Symbol == "GBP");
  
              // Again create a new context (to simulate making service calls over WCF)
              MyContext context4 = new MyContext(ConnectionString);
              context4.Customers.Add(customer);
  
              // Uncommenting the following line prevents the exception raised below
              //customer.Country.Currency = null;
  
              context4.Entry(customer.Country).State = System.Data.EntityState.Unchanged;
              context4.Entry(customer.Currency).State = System.Data.EntityState.Unchanged;
  
              // The following line will result in this exception:
              // AcceptChanges cannot continue because the object's key values conflict with another     
              // object in the ObjectStateManager. Make sure that the key values are unique before 
              // calling AcceptChanges.
              context4.Entry(customer.Country.Currency).State = System.Data.EntityState.Unchanged;
              context4.SaveChanges();
  
              Console.WriteLine("Done.");
              Console.ReadLine();
          }
      }
  
  
  
  }
  </code></pre>