1

I am using Entity Framework 7 in ASP.NET MVC app and try to save modified entity (from HTTP POST request) using InsertOrUpdate pattern from this topic. I also use this post (3rd method). This is my code:

private void insert_or_update<T>(T entity) where T : AbstractModel
{
    EntityState state;
    if (entity.ID == 0)
        state = EntityState.Added;
    else
        state = EntityState.Modified;

    dbcontext.Set<T>().Attach(entity);          //<- ERROR THERE
    dbcontext.Entry(entity).State = state;
    dbcontext.SaveChanges();
}

But I've got an error:

The instance of entity type 'Domain.Models.Section' 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 checked same questions there and I know, that repository shouldn't be added as an Singleton. This is my code from Startup.cs:

services.AddScoped<IRepository, EFRepository>();

Is there any way to fix this and use only one query to database?

For example, this method using 2 queries (from this question again)

var original = db.Users.Find(updatedUser.UserId);
if (original != null)
{
   db.Entry(original).CurrentValues.SetValues(updatedUser);
   db.SaveChanges();
}

UPD1: EF7 has no member CurrentValues for EntityEntry<T>. So last method can't be used.

UPD2: dbContext.Set<T>().Update() gets same error.

Community
  • 1
  • 1
Alexey Markov
  • 1,546
  • 2
  • 23
  • 41
  • 1
    It appears you have declared the `dbContext` outside of your function. This is definitely not recommended. Each function where database work is to occur should instantiate its own copy of the db context, do its work, and dispose of the context. Long-lived db contexts do nothing but cause problems. – Sam Axe Feb 02 '16 at 22:51
  • Could you show how are you calling repository method? Maybe it's something wrong there – tede24 Feb 02 '16 at 23:05
  • it appears your context is pretty big. However, right now there are two hotfixes to your problem (but this problem is only one that occurs with ambient DbContexts): First, you can get your entity from your context, and copy the correct values there. I do not believe updating FK's right there is a good idea though. Second possibility could be an ambient ChangeTracker, this could further amplify your problems though. – DevilSuichiro Feb 03 '16 at 06:14
  • I've got class `DatabaseContext` inherited inherited from `DbContext`. – Alexey Markov Feb 03 '16 at 06:46
  • *sorry, something going wrong with comment* I've got class `DatabaseContext` inherited inherited from `DbContext`. Then I have interface for repository `IRepository` and it's implementation `EFRepository` and It's get `DatabaseContext` in constructor. I inject the `EFRepository` using DI: `services.AddScoped();` Controllers get `IRepository` in constructor. So, every time controller created, constructor of `DbContext` and `EFRepository` call. So, **each funtion works with own instance of dbcontext**, isn't is? – Alexey Markov Feb 03 '16 at 06:52

0 Answers0