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.
// 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);
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.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With