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.

Cannot update the 1-m property out of DbContext

See original GitHub issue

I found an issue that EF Core cannot update an entity with a 1-m property if we update it out of DbContext, for example, I have two models Group and GroupItem, the Group has a set of GroupItems and every GroupItem belongs to one Group. In this case, if we updated a Group’s GroupItems out of DbContext, then DbContext cannot save the changes.

Attempted to update or delete an entity that does not exist in the store.

I think the exception means my GroupItem use a compiste key and which is changed so that EF Core cannot find any entity in the database, however, EF Core should support this situation as the code has a exact purpose, It’s obvious in below code that I want to update the Group(G-001)'s Items to value-1 and value-4.

// EFCoreTest.csproj

//<Project Sdk = "Microsoft.NET.Sdk" >
//  <PropertyGroup>
//    <TargetFramework>netcoreapp2.0</TargetFramework>
//    <IsPackable>false</IsPackable>
//  </PropertyGroup>
//  <ItemGroup>
//    <PackageReference Include = "Microsoft.EntityFrameworkCore" Version="2.0.0" />
//    <PackageReference Include = "Microsoft.EntityFrameworkCore.InMemory" Version="2.0.0" />
//    <PackageReference Include = "Microsoft.EntityFrameworkCore.Sqlite" Version="2.0.0" />
//    <PackageReference Include = "Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
//    <PackageReference Include = "Microsoft.NET.Test.Sdk" Version="15.3.0" />
//    <PackageReference Include = "xunit" Version="2.3.0" />
//    <PackageReference Include = "xunit.runner.visualstudio" Version="2.3.0" />
//  </ItemGroup>
//</Project>

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Xunit;

namespace EFCoreTest
{
    internal class Group
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public List<GroupItem> Items { get; set; }
    }
    internal class GroupItem
    {
        public string GroupId { get; set; }
        public string ItemValue { get; set; }
    }

    internal class EfContext : DbContext
    {
        public EfContext(DbContextOptions options) : base(options) { }

        public DbSet<Group> Groups { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<GroupItem>().HasKey(x => new { x.GroupId, x.ItemValue });

            modelBuilder.Entity<Group>().HasKey(x => x.Id);
            modelBuilder.Entity<Group>().HasMany(x => x.Items).WithOne().HasForeignKey(t => t.GroupId).IsRequired();
        }
    }

    internal static class MockContext
    {
        private static readonly ILoggerFactory DebugLogFactory = new LoggerFactory().AddDebug();

        public static EfContext UseInMemory(string databaseName = null)
        {
            var options = new DbContextOptionsBuilder<EfContext>()
                .UseInMemoryDatabase(databaseName ?? Guid.NewGuid().ToString())
                .UseLoggerFactory(DebugLogFactory)
                .Options;

            return new EfContext(options);
        }
    }

    public class UnitTest
    {
        [Fact]
        public async Task UpdateOutOfContextTest()
        {
            var group = new Group
            {
                Id = "G-001",
                Name = "group name",
                Items = new List<GroupItem> {
                    new GroupItem{ GroupId="G-001", ItemValue="value-1"},
                    new GroupItem{ GroupId="G-001", ItemValue="value-2"},
                    new GroupItem{ GroupId="G-001", ItemValue="value-3"}
                }
            };
            using (var ctx = MockContext.UseInMemory("UpdateTest"))
            {
                ctx.Groups.Add(group);
                await ctx.SaveChangesAsync();
            }

            // Update out of DbContext scope
            group.Name = "group name updated";
            group.Items = new List<GroupItem> {
                new GroupItem{ GroupId="G-001", ItemValue="value-1"},
                new GroupItem{ GroupId="G-001", ItemValue="value-4"}
            };
            using (var ctx = MockContext.UseInMemory("UpdateTest"))
            {
                ctx.Groups.Update(group);
                await ctx.SaveChangesAsync();  // Throw the exception below

                var g = await ctx.Groups.Include(x => x.Items).SingleAsync(x => x.Id == "G-001");
                Assert.Equal("group name updated", g.Name);
                Assert.Equal(new[] { "value-1", "value-4" }, g.Items.Select(x => x.ItemValue).ToArray());
            }
        }
    }
}
Message: Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException : 
Attempted to update or delete an entity that does not exist in the store.

Test Name:	EFCoreTest.UnitTest.UpdateOutOfContextTest
Test FullName:	EFCoreTest.UnitTest.UpdateOutOfContextTest
Test Source:	C:\Codes\Learn2017\EFCoreTest\UnitTest.cs : line 77
Test Outcome:	Failed
Test Duration:	0:00:00.156

Result StackTrace:	
at Microsoft.EntityFrameworkCore.Storage.Internal.InMemoryTable`1.Update(IUpdateEntry entry)
   at Microsoft.EntityFrameworkCore.Storage.Internal.InMemoryStore.ExecuteTransaction(IEnumerable`1 entries, IDiagnosticsLogger`1 updateLogger)
   at Microsoft.EntityFrameworkCore.Storage.Internal.InMemoryDatabase.SaveChangesAsync(IReadOnlyList`1 entries, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.<SaveChangesAsync>d__61.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.<SaveChangesAsync>d__59.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Microsoft.EntityFrameworkCore.DbContext.<SaveChangesAsync>d__48.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at EFCoreTest.UnitTest.<UpdateOutOfContextTest>d__0.MoveNext() in C:\Codes\Learn2017\EFCoreTest\UnitTest.cs:line 103
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
Result Message:	Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException : Attempted to update or delete an entity that does not exist in the store.

Further technical details

EF Core version: 2.0 Database Provider: Microsoft.EntityFrameworkCore.InMemory Operating system: Windows 10 Pro N 1709 IDE: Visual Studio Community 2017 Version 15.4.1

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:10 (1 by maintainers)

github_iconTop GitHub Comments

2reactions
Mike-E-angelocommented, Feb 20, 2020

In my case I was getting the exception discussed in this thread (first result in Google search) and I fixed it by changing this:

context.Entries.Add(new Model.AuthorizationEntry {Id = Guid.NewGuid(), Query = parameter.Query, Context = context});

to this:

context.Entries.Add(new Model.AuthorizationEntry {Query = parameter.Query, Context = context});

Which I am totally OK with. 😁

0reactions
dmitry-pavlovcommented, Jan 2, 2018

Sometimes Attempted to update or delete an entity that does not exist in the store. exception is raised when your DB scheme is not up to date. Make sure the database scheme is consistent with your entities.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Cannot update the 1-m property out of DbContext #10174
I found an issue that EF Core cannot update an entity with a 1-m property if we update it out of DbContext, for...
Read more >
Can't update object in Entity Framework
I notice that the retrieval of the Plan instance occurs via a _planQuery object, whereas the update occurs via a _planCommand object.
Read more >
Modifying data via the DbContext
The approach that you adopt to update/modify entities depends on whether the context is currently tracking the entity being modified or not.
Read more >
Update Data in Disconnected Scenario in Entity ...
Learn how to update data using Entity Framework Core in a disconnected scenario or web ... were modified out of the scope of...
Read more >
Disconnected Entities - EF Core
Working with disconnected, untracked entities across multiple context instances in Entity Framework Core.
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