question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

EF7 rc1-final: Error updateing entities

See original GitHub issue

I am creating an API using ASP.NET5 and recently updated completly to Entity Framework rc1-final, and when I try to execute, I get sometimes this Exception and sometimes the same code just works:

The instance of entity type ‘Asp5ApiSD.Models.Addon’ cannot be tracked because another instance of this type with the same key is already being tracked.

This should be the relative parts of my code:

    public class BCContext : DbContext
    {
        private readonly IConfiguration _config;
        public BCContext (DbContextOptions options)
: base(options)
        {
        }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            builder.Entity<Addon>(e =>
            {
                e.Property(c => c.IDaddon).ValueGeneratedOnAdd();
                e.HasKey(c => c.IDaddon);

            });

            base.OnModelCreating(builder);
        }
        public virtual DbSet<Addon> Addons { get; set; }
    }
    public interface IAddonRepository
    {
        List<Addon> SelectAll();
        Addon SelectByID(string id);
        void Insert(Addon obj);
        void Update(Addon obj);
        void Delete(string id);
    }
    public class AddonRepository : IAddonRepository
    {
        public BCContext Context { get; private set; }
        public AddonRepository(BCContext context)
        {
            this.Context = context;
        }

        public List<Addon> SelectAll()
        {
            return Context.Addons.ToList();
        }

        public Addon SelectByID(string id)
        {
            return Context.Addons.Where(i =>
                   i.IDaddon == Int32.Parse(id)).SingleOrDefault();
        }

        public void Insert(Addon obj)
        {
            Context.Entry(obj).State = EntityState.Added;
            Context.SaveChanges();
        }

        public void Update(Addon obj)
        {
            Context.Entry(obj).State = EntityState.Modified;
            Context.SaveChanges();
        }

        public void Delete(string id)
        {
            Addon obj = Context.Addons.SingleOrDefault(i => i.IDaddon == Int32.Parse(id));
            Context.Entry(obj).State = EntityState.Deleted;
            Context.SaveChanges();
        }
    }
    [Route("api/[controller]")]
    public class AddonController : Microsoft.AspNet.Mvc.Controller
    {
        public IAddonRepository _Repository { get; set; }

        public AddonController(IAddonRepository context)
        {
            _Repository = context;
            if (_Repository.SelectAll().Count != _addons.Count)
                _addons.AddRange(_Repository.SelectAll());
        }

        [HttpPost("{id}", Name = "SetAddonById")]
        public IActionResult UpdateItem(int id, [FromBody] Addon item)
        {
            if (item == null)
            {
                return HttpNotFound();
            }

            if (ModelState.IsValid)
            {
                _Repository.Update(item);
            }
            return new HttpStatusCodeResult(204); // 201 No Content
        }

    }
    public class Startup
    {

        public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
        {
            // Setup configuration sources.
            var builder = new ConfigurationBuilder()
                .SetBasePath(appEnv.ApplicationBasePath)
                .AddJsonFile("config.json")
                .AddEnvironmentVariables();
            Configuration = builder.Build();
        }

        public IConfiguration Configuration { get; set; }

        // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
            services.AddEntityFramework()
                    .AddSqlServer()
                    .AddDbContext<BCContext>(options => options.UseSqlServer(Configuration.Get<string>("Data:ConnectionString")));

            services.AddScoped<IAddonRepository, AddonRepository>();

        }

        public void Configure(IApplicationBuilder app)
        {
            app.UseMvc();
            app.UseWelcomePage();

            app.UseExceptionHandler("/Home/Error");
        }
    }
    [Table("Addon")]
    public class Addon
    {
        [Key]
        public int IDaddon { get; set; }
        public string Description { get; set; }
        public string Name { get; set; }
        public decimal Price { get; set; }
    }

The interessting thing is that sometimes I can’t update a single item and then I can make 10 upgrades behind each other. The code did also not work on Beta-8, I tought maybe a update to last version would solve it.

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Comments:11 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
rowanmillercommented, Nov 23, 2015

The idea was to “cache” the data to memory for performance reason.

The code has actually hurt perf quite a bit (and introduced thread-safety issues). A new instance of the controller is created for every request, so your call to _Repository.SelectAll() in the constructor is fetching every row from the database for every request, even though most of your actions probably only need one (or even zero) rows from the database. I would remove it.

BTW, because your repository is setup to not assume that an entity being passed to Update was already fetched from the same repository instance (and is therefore not tracked), you can also add AsNoTracking() to your queries. That will resolve your issue with the exception.

0reactions
sepeicommented, Nov 23, 2015

Thank you. I imagine the question why it worked from time to time. But solved and it can be closed. Sorry thought there was a problem on the framework.

Read more comments on GitHub >

github_iconTop Results From Across the Web

entity framework - EF7 'dnx ef update database' not working
i create a project to involve entity model and EF DBContext. then web project reference the project. run these commands, not working: dnx...
Read more >
EF7 (RC1) - Cannot Skip() and Take() in SQL Server 2008
I'm using "Microsoft.EntityFrameworkCore.SqlServer": "1.0.0-rc2-final" and according to this post, I would just need to add the option to.
Read more >
What's New in EF Core 7.0
These methods are applied to a LINQ query and will update or delete entities in the database based on the results of that...
Read more >
Microsoft.EntityFrameworkCore 7.0.10
Version Downloads Last updated 8.0.0‑preview.7.23375.4 8,798 12 days ago 8.0.0‑preview.6.23329.4 33,243 a month ago 8.0.0‑preview.5.23280.1 45,568 2 months ago
Read more >
Exploring Entity Framework Core 1.0.0 RTM Changes
Exploring Entity Framework Core 1.0.0 RTM Changes Understanding a breaking change in the update method behaviour between RC1 and RTM.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found