EF7 beta6: error saving multiple objects

I am creating an API using ASP.NET5 and Entity Framework 7.0.0-beta 6, and when I try to perform various updates in multiple requests, I get this exception:

A "company" cannot be traced because another instance of this type with the same key is already traced. For new objects, consider using the IIdentityGenerator generator to generate unique key values.

This is my code:

public class MrBellhopContext : DbContext { public DbSet<Company> Company { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Company>(entity => { entity.Key(c => c.CompanyId); entity.Index(c => c.Name); entity.Property(c => c.CompanyId).ValueGeneratedOnAdd(); }); modelBuilder.UseSqlServerIdentityColumns(); base.OnModelCreating(modelBuilder); } } public class Company { public int CompanyId { get; set; } public string Name { get; set; } public string Description { get; set; } public string Phone { get; set; } public string Email { get; set; } public short StatusId { get; set; } } public class CompanyRepository : ICompanyRepository { MrBellhopContext _dbcontext; public async Task UpdateAsync(Company company) { _dbcontext.Update(company); await _dbcontext.SaveChangesAsync(); } } [Route("api/[controller]")] public class CompanyController : Controller { [HttpPut] public async void UpdateAsync([FromBody] Company company) { if ((!ModelState.IsValid) || (company == null)) { Context.Response.StatusCode = 400; return; } else { await _repository.UpdateAsync(company); } } } 

I tried to solve this problem by removing ValueGeneratedOnAdd (), UseSqlServerIdentityColumns () or changing the mapping, but if I try to update multiple objects in multiple queries, I get an Exception:

  • First request: Update CompanyId 8
  • First request: upgrade CompanyId 9! ERROR

Does anyone know how to solve this problem?

+3
source share
3 answers

Solved: https://github.com/aspnet/EntityFramework/issues/2652

I added the repository as a Singleton:

 services.AddSigleton<Data.Interfaces.Company.ICompanyRepository,Data.Repositories.Company.CompanyRepository>(); 

This means that all requests share the same repository instance. You should reduce this to Scoped, so you have one repository instance for each request. In addition to avoiding the problem you are pushing, it also ensures that you do not get a giant instance of the context that keeps track of all the data from your database in memory.

To solve:

 services.AddScoped<Data.Interfaces.Company.ICompanyRepository,Data.Repositories.Company.CompanyRepository>(); 
+11
source

You get this error because your _repository instance already has a Company instance in memory with the same key. This can happen if you reuse the DbContext instance for streams. The above example does not contain code on how CompanyController._repository gets an instance. Make sure this is not shared between HTTP requests.

Also, put this line before configuring the key.

 entity.Property(c => c.CompanyId).ValueGeneratedOnAdd(); 
+2
source

Even I ran into the same problem.

I registered the repositories as singleton in the Configure method for the startup.cs file. Changing this parameter to AddScoped problem.

You just need to use the code below to update records

 _dbContext.Company.Update(company); _dbContext.SaveChanges(); 
0
source

All Articles