Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework 7 (Beta 7) and Entity Tracking

I am trying to separate my domain model (which is responsible for my business logic) with my data model which is what EF 7 uses to build my schema.

I am running into a problem with regards to persisting changes made to my domain model to my database

So for example given that I have the Data Model PersonTable and the Domain model Person:

public class PersonTable
{
    public virtual Guid Id { get; set; }
    public virtual String Name { get; set; }
    public virtual String Surname { get; set; }
}

public class Person
{
    public virtual Guid Id { get; set; }
    public virtual String Name { get; set; }
    public virtual String Surname { get; set; }
    //Other Domain Methods and Constructors...
}

And I want to persist my domain changes to my database by doing this:

public void Update(Person p)
{
    var person = new PersonTable
    {
        Id = p.Id,
        Name = p.Name,
        Surname = p.Surname
    }
    PersonDbContext.Update(person);
    PersonDbContext.SaveChanges();
}

When I try to apply these changes I get an InvalidOperationException saying

"The instance of entity type 'Tables.PersonTable' cannot be tracked because another instance of this type with the same key is already being tracked. For new entities consider using an IIdentityGenerator to generate unique key values."

I assume this has something to do with entity tracking but how does this work in EF 7? I want to be able to apply this pattern so that I can seperate these two models.

like image 699
Lutando Avatar asked Oct 07 '15 11:10

Lutando


2 Answers

// Before updating we have fetch original data row from database.
// So we need to use AsNoTracking().

var originalPerson = PersonDbContext.Person.AsNoTracking().FirstOrDefault(p => p.Id == id);

and at time of save we need to use following code.

PersonDbContext.Entry(originalPerson).Context.Update(newPersonDetail);
like image 109
Nikhil Tambave Avatar answered Sep 26 '22 01:09

Nikhil Tambave


The error occurs when your instance of PersonDbContext is already tracking an instance of Person with the same Id.

To debug this, inspect what you have tracking already in PersonDbContext.ChangeTracker.Entries(). I expect you will discover you already have an entry for PersonTable.Id that matches the one you are attempting to update.

To ensure you don't get these conflicts, don't reuse PersonDbContext across threads or multiple HTTP requests (if this is a web app.)

like image 29
natemcmaster Avatar answered Sep 22 '22 01:09

natemcmaster