Lutando
Lutando

Reputation: 5010

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.

Upvotes: 6

Views: 5289

Answers (3)

Nikhil Tambave
Nikhil Tambave

Reputation: 155

// 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);

Upvotes: 8

Akshar Patel
Akshar Patel

Reputation: 5777

I was facing the same error. I found the answer in this other thread here https://stackoverflow.com/a/31840042/1716912. I changed my repository DI to be scoped from being a singleton.

Upvotes: 2

natemcmaster
natemcmaster

Reputation: 26763

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.)

Upvotes: 3

Related Questions