Closed LittleLoveVN closed 2 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.
@LittleLoveVN Can you show the code for your entity types and any configuration that is happening in OnModelCreating?
EF Team Triage: Closing this issue as the requested additional details have not been provided and we have been unable to reproduce it.
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);
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
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.
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.
Duplicate of #7084
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.
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();
@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.
Thank you, that is exactly what I ended up doing!
@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
thank you so much, that is a great answer and is great help to me!
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.
@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.
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 :(
@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.
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 :)
I'm wondering tho if there is any significant performance loss with this approach? are there any benchmarks available? thanks again!
@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.
@rickco75 you do not need the .update (), only the saveChanges entity already monitors
@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.
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 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.
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 :(
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.
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.
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);
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);
When i'm trying to add continous same entity with difference key i has an error.
Stack Trace
Raw exception details:
project.json file:
With Entity Core 1.0 work, but after update to 1.1.0 has this error