title: Issue when inserting new entity with relationships to existing entities (Entity Framework Core 1.1.0 )
body: <p>I have encountered an issue when inserting (<code>Add</code> method of EF API) or updating (<code>Update</code> method of EF API) entities holding reference properties to existing entities (I call existing entity an entity that already exists in the database, and has its PK properly set).</p>
  
  <p>The model consists in <code>Place</code>, <code>Person</code>, <code>Address</code>, and <code>Status</code> :</p>
  
  <ul>
  <li>A person has many addresses.</li>
  <li>A place has several persons, and also
  several addresses.</li>
  <li>Places, Persons and Addresses have statuses.</li>
  <li>All entities have an Id, Name, Created date and Modified date (these fields are all defined in an abstract <code>BaseEntity</code>)</li>
  </ul>
  
  <p>If I create a whole graph for a "Place", with new Persons and new Addresses, and save it in one step, everything is fine.</p>
  
  <p>If I create a Place with Addreses then save it, it is still ok.
  But at last when I add an existing person and resave the Place, I have an exception: EF actually tries to insert the existing person, and SQL Server throws an error because EF tried to insert a row with a provided Id (PK are set to be generated by SQL Server).</p>
  
  <p>That means that by default, EF Core 1.1.0 looks like being unable to properly traverse relationships and discover which enitites should be added, and which one should be ignored or updated. It tries to insert an entity which already has its PK set to a positive value.</p>
  
  <p>After doing some research, I discovered the new <code>DbContext.ChangeTracker.Track()</code> method of the EF Core 1.1.0 API, and it allows one to execute a callback method on all the entities discovered by traversing the relationships of the root entity.
  Thanks to this, I have set up the appropriate State, according to the value of the primary key.</p>
  
  <p>Without this code (in <code>DbRepository.ApplyStates()</code>), none of my insert would work, as long as they would refer a relation to an existing entity.</p>
  
  <p>Note that with <strong>EF7 and the DNX CLI</strong>, this scenario would work, even without the DbRepository.ApplyStates() thing.</p>
  
  <p><strong>Source to reproduce</strong></p>
  
  <p><em>everything is in there: models, DbContext, Repository and test code.</em></p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.ComponentModel.DataAnnotations.Schema;
  using System.Linq;
  using Microsoft.EntityFrameworkCore;
  
  namespace EF110CoreTest
  {
      public class Program
      {
          public static void Main(string[] args)
          {
              Seed();
          }
  
          private static void Seed()
          {
              // Repo
              var statusRepo = new DbRepository&lt;Status&gt;();
              var personRepo = new DbRepository&lt;Person&gt;();
              var addressRepo = new DbRepository&lt;Address&gt;();
              var placeRepo = new DbRepository&lt;Place&gt;();
  
              // Status
              if (!statusRepo.GetAll().Any())
              {
                  statusRepo.InsertOrUpdate(new Status() { Name = "Active" });
                  statusRepo.InsertOrUpdate(new Status() { Name = "Archive" });
                  statusRepo.SaveChanges();
              }
              var statusActive = statusRepo.GetSingle(1);
              var statusArchive = statusRepo.GetSingle(2);
  
              // Delete the non static data
              foreach(var address in addressRepo.GetAll()) addressRepo.Delete(address);
              addressRepo.SaveChanges();
              foreach (var place in placeRepo.GetAll()) placeRepo.Delete(place);
              placeRepo.SaveChanges();
              foreach (var person in personRepo.GetAll()) personRepo.Delete(person);
              personRepo.SaveChanges();
  
              Console.WriteLine("Cleared any existing data");
  
              /***********************************************************************/
  
              // Step 1 : a person with status and addresses is saved
              var personWithAddresses = new Person()
              {
                  Name = "Jon SNOW",
                  Status = statusActive,
                  AddressCollection = new List&lt;Address&gt;()
                  {
                      new Address() { City = "Castleblack", Status = statusActive },
                      new Address() { City = "Winterfel", Status = statusArchive }
                  }
              };
              personRepo.InsertOrUpdate(personWithAddresses);
              personRepo.SaveChanges();
  
              Console.WriteLine("Step 1 ok");
              System.Threading.Thread.Sleep(1000);
  
              /***********************************************************************/
  
              // Step 2 : Create a place with addresses
              var placeWithAddress = new Place()
              {
                  Name = "Castleblack",
                  Status = statusActive
              };
              placeWithAddress.AddressCollection.Add(new Address() { City = "Castleblack", Status = statusActive });
              placeRepo.InsertOrUpdate(placeWithAddress);
              placeRepo.SaveChanges();
  
              Console.WriteLine("Step 2 ok");
              System.Threading.Thread.Sleep(1000);
  
              /***********************************************************************/
  
              // Step 3 : add person to this place
              placeWithAddress.PersonCollection.Add(personWithAddresses);
              placeRepo.InsertOrUpdate(placeWithAddress);
              placeRepo.SaveChanges();
  
              Console.WriteLine("Step 3 ok");
              System.Threading.Thread.Sleep(1000);
          }
      }
  
      public class DbRepository&lt;T&gt; where T : BaseEntity
      {
          protected readonly MyContext _context;
          public DbRepository() { _context = new MyContext(); }
  
          public T GetSingle(int id) =&gt; _context.Set&lt;T&gt;().FirstOrDefault(e =&gt; e.Id == id);
  
          public IEnumerable&lt;T&gt; GetAll() =&gt; _context.Set&lt;T&gt;().AsEnumerable();
  
          public void Insert(T entity)
          {
              ApplyStates(entity);
              _context.Add(entity);
          }
  
          public void Update(T entity)
          {
              ApplyStates(entity);
              _context.Update(entity);
          }
  
          public void Delete(T entity)
          {
              _context.Remove(entity);
          }
  
          private void ApplyStates(T entity)
          {
              _context.ChangeTracker.TrackGraph(entity, node =&gt;
              {
                  var entry = node.Entry;
                  var childEntity = (BaseEntity)entry.Entity;
                  entry.State = childEntity.IsNew ? EntityState.Added : EntityState.Modified;
              });
          }
  
          public void InsertOrUpdate(T entity)
          {
              if (entity.IsNew) Insert(entity); else Update(entity);
          }
  
          public void SaveChanges()
          {
              var pendingChanges = _context.ChangeTracker.Entries&lt;T&gt;()
                  .Where(entry =&gt; entry.State == EntityState.Added || entry.State == EntityState.Modified)
                  .Select(e =&gt; e.Entity)
                  .ToList();
              foreach (var entity in pendingChanges)
              {
                  entity.Modified = DateTime.Now;
                  if (entity.Created == null) entity.Created = DateTime.Now;
              }
              _context.SaveChanges();
          } 
      }
  
      #region Models
      public abstract class BaseEntity
      {
          public int Id { get; set; }
          public string Name { get; set; }
          public DateTime? Created { get; set; }
          public DateTime? Modified { get; set; }
          [NotMapped]
          public bool IsNew =&gt; Id &lt;= 0;
      }
  
      public class Person : BaseEntity
      {
          public int? StatusId { get; set; }
          public Status Status { get; set; }
          public List&lt;Address&gt; AddressCollection { get; set; } = new List&lt;Address&gt;(); 
      }
  
      public class Address : BaseEntity
      {
          public string Zip { get; set; }
          public string City { get; set; }
          public int? StatusId { get; set; }
          public Status Status { get; set; }
          public int? PersonId { get; set; }
          public Person Person { get; set; }
          public int? PlaceId { get; set; }
          public Place Place { get; set; }
      }
  
      public class Place : BaseEntity
      {
          public int? StatusId { get; set; }
          public Status Status { get; set; }
          public List&lt;Person&gt; PersonCollection { get; set; } = new List&lt;Person&gt;();
          public List&lt;Address&gt; AddressCollection { get; set; } = new List&lt;Address&gt;();  
      }
  
      public class Status : BaseEntity { }
      #endregion
  
      #region Context
      public class MyContext : DbContext
      {
          public DbSet&lt;Status&gt; StatusCollection { get; set; }
          public DbSet&lt;Person&gt; PersonCollection { get; set; } 
          public DbSet&lt;Address&gt; AddressCollection { get; set; }
          public DbSet&lt;Place&gt; PlaceCollection { get; set; }
  
          protected override void OnModelCreating(ModelBuilder builder)
          {
              // Basic event fire of model creation
              base.OnModelCreating(builder);
  
              // Status
              builder.Entity&lt;Status&gt;().ToTable("Status", "Shared");
  
              // Person
              builder.Entity&lt;Person&gt;().ToTable("Person", "Shared");
              builder.Entity&lt;Person&gt;()
                  .HasMany(p =&gt; p.AddressCollection)
                  .WithOne(a =&gt; a.Person);
  
              // Address
              builder.Entity&lt;Address&gt;().ToTable("Address", "Shared");
              builder.Entity&lt;Address&gt;()
                  .HasOne(p =&gt; p.Person)
                  .WithMany(a =&gt; a.AddressCollection);
  
              // Place
              builder.Entity&lt;Place&gt;().ToTable("Place", "Shared");
              builder.Entity&lt;Place&gt;()
                  .HasMany(p =&gt; p.AddressCollection)
                  .WithOne(p =&gt; p.Place);
          }
  
          protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
          {
              optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=EF110CoreTest;Trusted_Connection=True;");
          }
      }
      #endregion
  }
  </code></pre>
  
  <p><strong>Project.json file</strong></p>
  
  <p>{
      "version": "1.0.0-*",
      "buildOptions": {
        "emitEntryPoint": true
      },</p>
  
  <pre><code>"dependencies": {
    "Microsoft.EntityFrameworkCore": "1.1.0",
    "Microsoft.EntityFrameworkCore.SqlServer": "1.1.0",
    "Microsoft.EntityFrameworkCore.Tools": "1.1.0-preview4-final"
  },
  
  "frameworks": {
    "net461": {}
  },
  
  "tools": {
    "Microsoft.EntityFrameworkCore.Tools.DotNet": "1.0.0-preview3-final"
  }
  </code></pre>
  
  <p>}</p>
  
  <p><strong>Exception details</strong></p>
  
  <p>Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details. ---> System.Data.SqlClient.SqlException: Cannot insert explicit value for identity column in table 'Person' when IDENTITY_INSERT is set to OFF.</p>