dotnet / efcore

EF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.
https://docs.microsoft.com/ef/
MIT License
13.82k stars 3.2k forks source link

Cannot be tracked because another instance of this type with the same key is already being tracked #7064

Closed LittleLoveVN closed 2 years ago

LittleLoveVN commented 8 years ago

When i'm trying to add continous same entity with difference key i has an error.

var trans = _context.Database.BeginTransaction();
            NhomNguoiDung nnd = new NhomNguoiDung()
            {
                NhomNguoiDung_Ma = Guid.NewGuid(),
                NhomNguoiDung_Ten = "Administrators"
            };
            _context.Add(nnd);

            NguoiDung nd = new NguoiDung()
            {
                NguoiDung_Ma = Guid.NewGuid(),
                NguoiDung_TaiKhoan = "Administrator",
                NguoiDung_MatKhau = "-----+++-----"
            };
            _context.Add(nd);

            PhanNhomNguoiDung pnnd = new PhanNhomNguoiDung()
            {
                PhanNhomNguoiDung_NguoiDung = nd.NguoiDung_Ma,
                PhanNhomNguoiDung_NhomNguoiDung = nnd.NhomNguoiDung_Ma
            };
            _context.Add(pnnd);
            foreach(var t  in Roles.ListOfRole()) // List of role about 24 role with difference name
            {
                var qh = new QuyenHan()
                {
                    QuyenHan_Ma = Guid.NewGuid(),
                    QuyenHan_Ten = t
                };
                _context.Add(qh); // 2nd item add OK

                var pqnnd = new PhanQuyenNhomNguoiDung() // PhanQuyenNhomNguoiDung_NhomNguoiDung & PhanQuyenNhomNguoiDung_QuyenHan  Is Primarykey
                {
                    PhanQuyenNhomNguoiDung_NhomNguoiDung = nnd.NhomNguoiDung_Ma,
                    PhanQuyenNhomNguoiDung_QuyenHan = qh.QuyenHan_Ma // new Key but error for what ???
                };
               // 2nd item add has ERROR
                _context.PhanQuyenNhomNguoiDung.Add(pqnnd);
            };`

Stack Trace

An unhandled exception occurred while processing the request.

InvalidOperationException: The instance of entity type 'PhanQuyenNhomNguoiDung' cannot be tracked because another instance of this type with the same key is already being tracked. When adding new entities, for most key types a unique temporary key value will be created if no key is set (i.e. if the key property is assigned the default value for its type). If you are explicitly setting key values for new entities, ensure they do not collide with existing entities or temporary values generated for other new entities. When attaching existing entities, ensure that only one entity instance with a given key value is attached to the context. Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap.Add(TKey key, InternalEntityEntry entry)

Stack Query Cookies Headers InvalidOperationException: The instance of entity type 'PhanQuyenNhomNguoiDung' cannot be tracked because another instance of this type with the same key is already being tracked. When adding new entities, for most key types a unique temporary key value will be created if no key is set (i.e. if the key property is assigned the default value for its type). If you are explicitly setting key values for new entities, ensure they do not collide with existing entities or temporary values generated for other new entities. When attaching existing entities, ensure that only one entity instance with a given key value is attached to the context. Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap.Add(TKey key, InternalEntityEntry entry) Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap.Add(InternalEntityEntry entry) Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.StartTracking(InternalEntityEntry entry) Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState oldState, EntityState newState, bool acceptChanges) Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.PaintAction(EntityEntryGraphNode node) Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityEntryGraphIterator.TraverseGraph(EntityEntryGraphNode node, Func<EntityEntryGraphNode, bool> handleNode) Microsoft.EntityFrameworkCore.DbContext.SetEntityState(TEntity entity, EntityState entityState) QuanLyDoanVien.Controllers.SetupController.InitData() in SetupController.cs + _context.PhanQuyenNhomNguoiDung.Add(pqnnd); QuanLyDoanVien.Controllers.SetupController.InitData(string key) in SetupController.cs + InitData(); lambda_method(Closure , object , Object[] ) Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+d27.MoveNext() System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+d25.MoveNext() Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context) Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted) Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+d22.MoveNext() Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ResourceExecutedContext context) Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted) Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+d20.MoveNext() System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) Microsoft.AspNetCore.Builder.RouterMiddleware+d4.MoveNext() System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) Microsoft.AspNetCore.Authentication.AuthenticationMiddleware+d18.MoveNext() Microsoft.AspNetCore.Authentication.AuthenticationMiddleware+d18.MoveNext() System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) Microsoft.AspNetCore.Session.SessionMiddleware+d9.MoveNext() Microsoft.AspNetCore.Session.SessionMiddleware+d9.MoveNext() System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) Microsoft.VisualStudio.Web.BrowserLink.Runtime.BrowserLinkMiddleware+d7.MoveNext() System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.MigrationsEndPointMiddleware+d5.MoveNext() System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware+d6.MoveNext() Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware+d6.MoveNext() System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware+d7.MoveNext()

Show raw exception details

Raw exception details:

System.InvalidOperationException: The instance of entity type 'PhanQuyenNhomNguoiDung' cannot be tracked because another instance of this type with the same key is already being tracked. When adding new entities, for most key types a unique temporary key value will be created if no key is set (i.e. if the key property is assigned the default value for its type). If you are explicitly setting key values for new entities, ensure they do not collide with existing entities or temporary values generated for other new entities. When attaching existing entities, ensure that only one entity instance with a given key value is attached to the context.
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.Add(TKey key, InternalEntityEntry entry)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.Add(InternalEntityEntry entry)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.StartTracking(InternalEntityEntry entry)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState oldState, EntityState newState, Boolean acceptChanges)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.PaintAction(EntityEntryGraphNode node)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityEntryGraphIterator.TraverseGraph(EntityEntryGraphNode node, Func`2 handleNode)
   at Microsoft.EntityFrameworkCore.DbContext.SetEntityState[TEntity](TEntity entity, EntityState entityState)
   at QuanLyDoanVien.Controllers.SetupController.InitData() in T:\Projects\QuanLyDoanVien\src\QuanLyDoanVien\Controllers\SetupController.cs:line 134
   at QuanLyDoanVien.Controllers.SetupController.InitData(String key) in T:\Projects\QuanLyDoanVien\src\QuanLyDoanVien\Controllers\SetupController.cs:line 43
   at lambda_method(Closure , Object , Object[] )
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__27.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextActionFilterAsync>d__25.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextResourceFilter>d__22.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ResourceExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeAsync>d__20.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware`1.<Invoke>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Session.SessionMiddleware.<Invoke>d__9.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Session.SessionMiddleware.<Invoke>d__9.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.VisualStudio.Web.BrowserLink.Runtime.BrowserLinkMiddleware.<ExecuteWithFilter>d__7.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.MigrationsEndPointMiddleware.<Invoke>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.<Invoke>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.<Invoke>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.<Invoke>d__7.MoveNext()

project.json file:

"dependencies": {
    "Microsoft.AspNetCore.Authentication.Cookies": "1.1.0",
    "Microsoft.AspNetCore.Diagnostics": "1.1.0",
    "Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore": "1.1.0",
    "Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.1.0",
    "Microsoft.AspNetCore.Mvc": "1.1.0",
    "Microsoft.AspNetCore.Mvc.Razor": "1.1.0",
    "Microsoft.AspNetCore.Razor.Tools": {
      "version": "1.1.0-preview4-final",
      "type": "build"
    },
    "Microsoft.AspNetCore.Routing": "1.1.0",
    "Microsoft.AspNetCore.Server.IISIntegration": "1.1.0",
    "Microsoft.AspNetCore.Server.Kestrel": "1.1.0",
    "Microsoft.AspNetCore.Session": "1.1.0",
    "Microsoft.AspNetCore.StaticFiles": "1.1.0",
    "Microsoft.EntityFrameworkCore.SqlServer": "1.1.0",
    "Microsoft.EntityFrameworkCore.SqlServer.Design": {
      "version": "1.1.0",
      "type": "build"
    },
    "Microsoft.EntityFrameworkCore.Tools": {
      "version": "1.1.0-preview4-final",
      "type": "build"
    },
    "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0",
    "Microsoft.Extensions.Configuration.Json": "1.1.0",
    "Microsoft.Extensions.Configuration.UserSecrets": "1.1.0",
    "Microsoft.Extensions.Logging": "1.1.0",
    "Microsoft.Extensions.Logging.Console": "1.1.0",
    "Microsoft.Extensions.Logging.Debug": "1.1.0",
    "Microsoft.Extensions.Options.ConfigurationExtensions": "1.1.0",
    "Microsoft.Framework.Caching.Memory": "1.0.0-beta8",
    "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.1.0",
    "Microsoft.VisualStudio.Web.CodeGeneration.Tools": {
      "version": "1.1.0-preview4-final",
      "type": "build"
    },
    "Microsoft.VisualStudio.Web.CodeGenerators.Mvc": {
      "version": "1.1.0-preview4-final",
      "type": "build"
    }
  },

With Entity Core 1.0 work, but after update to 1.1.0 has this error

VagueGit commented 8 years ago

@LittleLoveVN does the item you are adding have an alternate key? I had this issue trying to add items that have an alternate key. The alternate key must also be unique.

ajcvickers commented 8 years ago

@LittleLoveVN Can you show the code for your entity types and any configuration that is happening in OnModelCreating?

rowanmiller commented 8 years ago

EF Team Triage: Closing this issue as the requested additional details have not been provided and we have been unable to reproduce it.

LittleLoveVN commented 7 years ago

Sorry! I'm return. Here is OnModelCreating(ModelBuilder modelBuilder):

modelBuilder.Entity<NguoiDung>()
    .HasKey(t => t.NguoiDung_Ma);

modelBuilder.Entity<NguoiDung>()
    .HasIndex(t => t.NguoiDung_TaiKhoan)
    .IsUnique(true);
modelBuilder.Entity<NhomNguoiDung>()
    .HasKey(t => t.NhomNguoiDung_Ma);

modelBuilder.Entity<NhomNguoiDung>()
    .HasIndex(t => t.NhomNguoiDung_Ten)
    .IsUnique(true);

modelBuilder.Entity<PhanNhomNguoiDung>()
    .HasKey(t => new { t.PhanNhomNguoiDung_NguoiDung, t.PhanNhomNguoiDung_NhomNguoiDung });

modelBuilder.Entity<PhanNhomNguoiDung>()
    .HasOne(t => t.NguoiDung)
    .WithMany(t => t.PhanNhomNguoiDung)
    .HasForeignKey(t => t.PhanNhomNguoiDung_NguoiDung)
    .HasPrincipalKey(t => t.NguoiDung_Ma);

modelBuilder.Entity<PhanNhomNguoiDung>()
    .HasOne(t => t.NhomNguoiDung)
    .WithMany(t => t.PhanNhomNguoiDung)
    .HasForeignKey(t => t.PhanNhomNguoiDung_NhomNguoiDung)
    .HasPrincipalKey(t => t.NhomNguoiDung_Ma);

modelBuilder.Entity<QuyenHan>()
    .HasKey(t => t.QuyenHan_Ma);

modelBuilder.Entity<QuyenHan>()
    .HasIndex(t => t.QuyenHan_Ten)
    .IsUnique(true);

modelBuilder.Entity<PhanQuyenNhomNguoiDung>()
    .HasKey(t => new { t.PhanQuyenNhomNguoiDung_NhomNguoiDung, t.PhanQuyenNhomNguoiDung_QuyenHan });

modelBuilder.Entity<PhanQuyenNhomNguoiDung>()
    .HasOne(t => t.NhomNguoiDung)
    .WithMany(t => t.PhanQuyenNhomNguoiDung)
    .HasForeignKey(t => t.PhanQuyenNhomNguoiDung_NhomNguoiDung)
    .HasPrincipalKey(t => t.NhomNguoiDung_Ma)
    .IsRequired(true);

modelBuilder.Entity<PhanQuyenNhomNguoiDung>()
    .HasOne(t => t.QuyenHan)
    .WithMany(t => t.PhanQuyenNhomNguoiDung)
    .HasForeignKey(t => t.PhanQuyenNhomNguoiDung_QuyenHan)
    .HasPrincipalKey(t => t.QuyenHan_Ma)
    .IsRequired(true);
LittleLoveVN commented 7 years ago

My code run in .net core ver 1.0, but in 1.1 has error. I don't know how to fix it!!! @rowanmiller @VagueGit @ajcvickers

LittleLoveVN commented 7 years ago

I found where it make error but don't know how to fix it. EF generate database wrong.

    public class PhanQuyenNhomNguoiDung
    {
        [Key]
        [Column(Order = 1)]
        [Display(Name = "Nhóm người dùng")]
        public Guid PhanQuyenNhomNguoiDung_NhomNguoiDung { get; set; }

        [Key]
        [Column(Order = 2)]
        [Display(Name = "Quyền hạn")]
        public Guid PhanQuyenNhomNguoiDung_QuyenHan { get; set; }

        public virtual NhomNguoiDung NhomNguoiDung { get; set; }
        public virtual QuyenHan QuyenHan { get; set; }
    }

EF generate a constraint:

CONSTRAINT [AK_PhanQuyenNhomNguoiDung_PhanQuyenNhomNguoiDung_NhomNguoiDung] UNIQUE NONCLUSTERED 
(
    [PhanQuyenNhomNguoiDung_NhomNguoiDung] ASC
)

After I remove Key attribute it's working fine. Thank EF team.

divega commented 7 years ago

Reopening since new repro information was provided.

@LittleLoveVN can you clarify if the key is being configured using the fluent API as in

 modelBuilder.Entity<PhanQuyenNhomNguoiDung>()
                .HasKey(t => new { t.PhanQuyenNhomNguoiDung_NhomNguoiDung, t.PhanQuyenNhomNguoiDung_QuyenHan });

or [Key] attribute as in your previous comment, or using both? As far as I remember EF Core does not support using KeyAttribute to configure composite keys, but I am not sure if this is the root cause of what you are seeing.

Note for triage: this could be a regression going from 1.0 to 1.1.

ajcvickers commented 7 years ago

Duplicate of #7084

rickco75 commented 7 years ago

image

I'm getting the same error, i am trying to do a PUT request on an api and check to see if the record actually exists first. any help would be appreciated

InvalidOperationException: The instance of entity type 'Contract' cannot be tracked because another instance of this type with the same key is already being tracked. When adding new entities, for most key types a unique temporary key value will be created if no key is set (i.e. if the key property is assigned the default value for its type). If you are explicitly setting key values for new entities, ensure they do not collide with existing entities or temporary values generated for other new entities. When attaching existing entities, ensure that only one entity instance with a given key value is attached to the context.

amitvasdev01 commented 7 years ago

I was getting this error than i used code in this way, in my case i was updating an entity so i was getting this error, now i am using this thing in older way as below there is no error.

          RestaurantDetail objrest = new RestaurantDetail();
            objrest.address1 = model.address1;
            objrest.city = model.city;
            objrest.state = model.state;
            objrest.intro = model.intro;
            objrest.restaurantName = model.restaurantName;
            objrest.createdDate = DateTime.Now;
            objrest.modifiedDate = DateTime.Now;
            objrest.id = Convert.ToInt32(Id);
            _context.Update(objrest);
            _context.SaveChanges();
nimeshvaghasiya commented 7 years ago

@rickco75 I had same issue and get rid of it by below: In your case it will be: var record2 = _context.Contracts.AsNoTracking().Where(t => t.Id== id).FirstOrDefault();

AsNoTracking() may help you.

rickco75 commented 7 years ago

Thank you, that is exactly what I ended up doing!

smitpatel commented 7 years ago

@rickco75 - When you query the database for record2 without using AsNoTracking EF will start tracking it in current context. So when you update contract in your code, EF finds multiple entities with same id hence the error. AsNoTracking is one solution as you are querying record2 just to find out the existence of entity and you don't want EF to track any modifications to that (since you are not modifying it). In many cases not having AsNoTracking is fine as long as you don't add/attach/update entity with same id in the context. But it is good to have it explicitly when tracking is not required.

Also, if you are just checking for existence then a query with count would be much better option. something like this _context.Contracts.Where(c => c.Id == id).Count() The benefits are

rickco75 commented 7 years ago

thank you so much, that is a great answer and is great help to me!

mhamri commented 6 years ago

actually, it doesn't make sense, in lifetime a request maybe I need to fetch one item multiple times in different scope of the program. sometimes the item even mapped with automapper, sometimes same item that are shared between different tables are coming multiple times. the thing that should be important is the time that i'm asking for savechanges. if an item is already marked with a key, means that item by that key should be referenced in the lifetime of a request, not a new item created in each query. if I query 10 times for an entity. then change tracker should create 10 different item of that entity? our team almost every day is facing this issue and just because of this behavior efcore became a bottleneck

assume this scenario

class Acitvity{
    public int Id { get; set; }
    public SimpleConfig SimpleConfig {get;set;}
}

class Project {
    public int Id { get; set; }
    public SimpleConfig SimpleConfig {get;set;}
}

class SimpleConfig{
    public int Id { get; set; }
    public string Key { get; set; }
    public string Value { get; set; }    
}

if i query Project and Activity in same request and both of them refering to the same SimpleConfig and i try to update either Activity or Project. then i will face this kind of error

InvalidOperationException: The instance of entity type 'SimpleConfig' cannot be tracked because another instance with the key value 'Id:5' is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.

and manual detaching make the code unreadable, I gave a simple example here, we have very complex scenario that I need to detach and attach each object line by line that doesn't make sense again. because it's the change tracker job.

ajcvickers commented 6 years ago

@mhamri Sounds like the same context instance is being used for multiple units-of-work. I would suggest using short-lived context instances that do one thing. This might mean registering your context as a transient service if you are using D.I. and many different things happen in a single scope.

kmute90 commented 6 years ago

I tried it with Transient DbContext, but the same error is happening, is there any way to resolve this error? I cannot save my entity :(

ajcvickers commented 6 years ago

@kmute90 This is a closed issue. If you are seeing something that you think is a bug, then please open a new issue and provide full details including a runnable project/solution or full code listing that demonstrates the behavior you are seeing.

kmute90 commented 6 years ago

Sorry, actually it worked, i messed up setting every service in the chain transient, I actually came here to delete my last comment but you were faster :)

kmute90 commented 6 years ago

I'm wondering tho if there is any significant performance loss with this approach? are there any benchmarks available? thanks again!

ajcvickers commented 6 years ago

@kmute90 Hard to say for sure without knowing the specific details, but DbContext is designed to be used for a short lifetime and then be disposed. You may also be able to use DbContext pooling, which is more restrictive, but may give an additional perf boost.

ulric03 commented 6 years ago

@rickco75 you do not need the .update (), only the saveChanges entity already monitors

sksallaj82 commented 6 years ago

@rickco75 you do not need the .update (), only the saveChanges entity already monitors No idea why this works.. but this works.. the Update was messing me up, when i removed it, any changes I made to the object worked. Wow.

avjabalpur commented 5 years ago

Hi All,

I got the same issue in my unit test

The instance of entity type 'Patient' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.

Not sure how I can fix this.

abedkanbar commented 5 years ago

Hi All,

I got the same issue in my unit test

The instance of entity type 'Patient' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.

Not sure how I can fix this.

Hi, In your "OnConfiguring" method, you can use:

optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);

I hope it will be resolved.

ghost commented 5 years ago

The same situation. I also use Automapper. EF think that the model is new, but the model was just mapped.

optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);

It doen't help :(

hendrik-123 commented 5 years ago

I had the same error. During setup I added some test records starting with id 1. It appeared that the in memory database also starts numbering at 1 when new records are added, causing the "entity already tracked" error.

After I changed my initialization code to use ids as of 101, the problem was solved.

ajcvickers commented 5 years ago

Please note that this issue is closed. If you are running into a problem with one of the latest releases (2.2 or 3.0 preview) that you believe is a bug, then please file a new issue and include a small, runnable project/solution complete code listing that demonstrates the behavior so that we can investigate.

ghost commented 5 years ago

This approach can help solve the problem:

            var existing = await this.entityDbSet.FindAsync(entity.Id);
            if (existing != null)
            {
                this.context.Entry(existing).CurrentValues.SetValues(entity);
            }

            await this.context.SaveChangesAsync(token);
urza commented 4 years ago

I encountered the same problem.

I have asp core .net 5 rc1 with EF Core

I have middleware that has DbContext (by default Scoped) injected in the Init method and does some user-related object selection that is then passed to BaseController from which actual controllers are inheriting, so that the user-related selection only happens once. Then I have classic update scenario, when user sends updated values from form.

The default code generated by Visual Studio in the update method caused the "Cannot be tracked because another instance.." exception.

This helped to solve the issue:

This approach can help solve the problem:

            var existing = await this.entityDbSet.FindAsync(entity.Id);
            if (existing != null)
            {
                this.context.Entry(existing).CurrentValues.SetValues(entity);
            }

            await this.context.SaveChangesAsync(token);