2014-04-21 16:58:45 8 Comments
In a nutshell the exception is thrown during POSTing wrapper model and changing the state of one entry to 'Modified'. Before changing the state, the state is set to 'Detached' but calling Attach() does throw the same error. I'm using EF6.
Please find my code below(model names have been changed to make it easier to read)
Model
// Wrapper classes
public class AViewModel
{
public A a { get; set; }
public List<B> b { get; set; }
public C c { get; set; }
}
Controller
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
if (!canUserAccessA(id.Value))
return new HttpStatusCodeResult(HttpStatusCode.Forbidden);
var aViewModel = new AViewModel();
aViewModel.A = db.As.Find(id);
if (aViewModel.Receipt == null)
{
return HttpNotFound();
}
aViewModel.b = db.Bs.Where(x => x.aID == id.Value).ToList();
aViewModel.Vendor = db.Cs.Where(x => x.cID == aViewModel.a.cID).FirstOrDefault();
return View(aViewModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(AViewModel aViewModel)
{
if (!canUserAccessA(aViewModel.a.aID) || aViewModel.a.UserID != WebSecurity.GetUserId(User.Identity.Name))
return new HttpStatusCodeResult(HttpStatusCode.Forbidden);
if (ModelState.IsValid)
{
db.Entry(aViewModel.a).State = EntityState.Modified; //THIS IS WHERE THE ERROR IS BEING THROWN
db.SaveChanges();
return RedirectToAction("Index");
}
return View(aViewModel);
}
As shown above line
db.Entry(aViewModel.a).State = EntityState.Modified;
throws exception:
Attaching an entity of type 'A' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.
Does anybody see anything wrong in my code or understand in what circumstances it would throw such error during editing a model?
Related Questions
Sponsored Content
3 Answered Questions
[SOLVED] Attaching an entity of type 'X' failed because another entity of the same type already has the same primary key value
- 2016-12-29 08:53:34
- javad hemati
- 21289 View
- 8 Score
- 3 Answer
- Tags: c# asp.net-mvc entity-framework
1 Answered Questions
[SOLVED] Failed because another entity of the same type already has the same primary key value As
- 2018-05-11 13:09:06
- Mehrdad Ghaffari
- 1213 View
- 1 Score
- 1 Answer
- Tags: c# asp.net-mvc entity-framework
0 Answered Questions
EF: 'Attaching an entity of type 'ENTITY NAME' failed because another entity of the same type already has the same primary key value
- 2018-04-22 06:17:32
- ibamboo
- 78 View
- 0 Score
- 0 Answer
- Tags: c# .net entity-framework
1 Answered Questions
[SOLVED] Attaching an entity of type 'XXX' failed because another entity of the same type already has the same primary key value
- 2018-03-28 09:37:50
- Ibtisam
- 706 View
- 0 Score
- 1 Answer
- Tags: c# .net entity-framework entity-framework-6 repository-pattern
1 Answered Questions
[SOLVED] Attaching an entity of type 'Quiz.DAL.Answer' failed because another entity of the same type already has the same primary key value
- 2017-09-27 18:29:59
- Stefan Ivovic
- 216 View
- 0 Score
- 1 Answer
- Tags: c# asp.net asp.net-mvc entity-framework
1 Answered Questions
[SOLVED] Attaching an entity of type 'XXX.EnquiryLineItem' failed because another entity of the same type already has the same primary key value
- 2017-09-21 18:48:31
- user2695433
- 1365 View
- 0 Score
- 1 Answer
- Tags: c# asp.net-mvc entity-framework
3 Answered Questions
[SOLVED] Attaching an entity of type failed because another entity of the same type already has the same primary key value.
- 2014-05-28 21:40:50
- user3618052
- 19993 View
- 6 Score
- 3 Answer
- Tags: c# entity-framework model-view-controller primary-key
1 Answered Questions
ASP.NET MVC - Attaching an entity of type 'X' failed
- 2016-03-25 18:46:15
- Serkan
- 1219 View
- 0 Score
- 1 Answer
- Tags: c# asp.net-mvc entity-framework
7 Answered Questions
[SOLVED] Entity Framework 5 Updating a Record
- 2013-03-11 10:27:12
- Stokedout
- 426942 View
- 832 Score
- 7 Answer
- Tags: c# asp.net-mvc-3 entity-framework-5
3 Answered Questions
[SOLVED] EF, Automapper exception, "Attaching an entity of type ... failed because another entity of the same type already has the same primary key value"
- 2015-08-05 11:19:24
- arame3333
- 6523 View
- 0 Score
- 3 Answer
- Tags: c# entity-framework automapper
15 comments
@Suzume 2018-10-02 16:30:30
I solve this problem with a "using" block
Here is where I get the idea https://social.msdn.microsoft.com/Forums/sqlserver/es-ES/b4b350ba-b0d5-464d-8656-8c117d55b2af/problema-al-modificar-en-entity-framework?forum=vcses is in spanish (look for the second answer)
@Suzume 2018-10-02 16:49:55
just be careful and only use 1 instance of database conexion, specially if you are using entity framework if you don't do it you will get the error Entity Framework An entity object cannot be referenced by multiple instances of IEntityChangeTracker
@Prem Kumar 2018-03-16 13:43:12
I had a similar issue, after probing for 2-3 days found ".AsNoTracking" should be removed as EF doesn't track the changes and assumes there are no changes unless an object is attached. Also if we don't use .AsNoTracking, EF automatically knows which object to save/update so there is no need to use Attach/Added.
@Cássio Batista Pereira 2017-06-30 00:06:34
Try this:
@veeresh i 2017-06-14 17:10:58
i mange to fix the issue by updating state. when you trigger find or any other query operation on the same record sate has been updated with modified so we need to set status to Detached then you can fire your update change
@lvl4fi4 2017-05-13 23:04:43
I had this problem with local var and i just detach it like this:
Problem causes of loaded objects with same Key, so first we will detach that object and do the the updating to avoid conflict between two object with the same Key
@lvl4fi4 2017-05-13 23:45:13
@Artjom B Problem causes of loaded objects with same Key, so first we will detach that object and do the the updating to avoid conflict between two object with the same Key
@Chris Ciszak 2014-04-22 18:58:31
Problem SOLVED!
Attach
method could potentially help somebody but it wouldn't help in this situation as the document was already being tracked while being loaded in Edit GET controller function. Attach would throw exactly the same error.The issue I encounter here was caused by function
canUserAccessA()
which loads the A entity before updating the state of object a. This was screwing up the tracked entity and it was changing state of a object toDetached
.The solution was to amend
canUserAccessA()
so that the object I was loading wouldn't be tracked. FunctionAsNoTracking()
should be called while querying the context.For some reason I couldnt use
.Find(aID)
withAsNoTracking()
but it doesn't really matter as I could achieve the same by changing the query.Hope this will help anybody with similar problem!
@Brent 2014-07-08 10:40:49
slightly neater and more performant: if (db.As.AsNoTracking().Any(x => x.aID == aID && x.UserID==userID))
@Maxime 2015-06-12 13:39:58
Note: you need
using System.Data.Entity;
to useAsNoTracking()
.@Anton Lyhin 2015-12-10 22:34:25
In my case updating only fields except entity id worked fine: var entity = context.Find(entity_id); entity.someProperty = newValue; context.Entry(entity).Property(x => x.someProperty).IsModified = true; context.SaveChanges();
@coggicc 2016-03-01 03:52:32
Massive Help. I added the .AsNoTracking() before my FirstOrDefault() and it worked.
@erhan355 2016-12-29 12:38:37
Here what I did in the similar case.
That sitatuation means that same entity has already been existed in the context.So following can help
First check from ChangeTracker if the entity is in the context
If it exists
@Murat Yıldız 2016-09-18 12:22:12
This problem may also be seen during
ViewModel
toEntityModel
mapping (by usingAutoMapper
, etc.) and trying to includecontext.Entry().State
andcontext.SaveChanges()
such a using block as shown below would solve the problem. Please keep in mind thatcontext.SaveChanges()
method is used two times instead of using just afterif-block
as it must be in using block also.Hope this helps...
@Jared Beach 2016-07-19 20:58:43
Similar to what Luke Puplett is saying, the problem can be caused by not properly disposing or creating your context.
In my case, I had a class which accepted a context called
ContextService
:My context service had a function which updates an entity using an instantiated entity object:
All of this was fine, my controller where I initialized the service was the problem. My controller originally looked like this:
I changed it to this and the error went away:
@add-Naan 2015-09-14 16:41:07
for me the local copy was the source of the problem. this solved it
@guneysus 2015-08-02 11:20:34
Interestingly:
Or if you still is not generic:
seems to solved my problem smoothly.
@firecape 2016-01-21 13:08:56
Amazing, that worked perfect in my scenario where I was needing to update records in a many to many with a custom join table in a disconnected app. Even with the entity grabbed from the database, I was getting referential errors, etc. I was using "context.Entry(score).State = System.Data.Entity.EntityState.Modified;" but this finally worked! Thank you!!
@Khainestar 2016-02-03 16:51:05
This works. All the other suggestions about attaching and using notracking failed as I was already doing noTracking. Thanks for the solution.
@Ian 2016-03-07 17:02:56
This worked for me whilst updating parent and child entities within the same unit of work. many thanks
@Nick 2016-03-29 15:28:19
For anyone looking,
AddOrUpdate
is an extension method in theSystem.Data.Entity.Migrations
namespace.@Artyomska 2017-07-28 14:05:23
Do you know if there is an equivalent for "DbContext.Entry(entity).State = EntityState.Deleted;" this, like the AddOrUpdate function is for EntityState=Added or EntityState=Deleted ? Your method worked well for Add or Update, but I still receive the OP error in my Delete function.
@guneysus 2017-07-28 14:14:55
@Artyomska Unfortunately I do not know.
@Avi Kenjale 2017-08-15 16:49:20
@guneysus, I had same question where your suggestion worked. However, my question is little different. If you can have a look on this Question would be good.
@Jon 2018-07-30 18:30:13
Can anyone explain why this works and setting the state to modified doesn't?
@sephirot 2015-06-23 09:04:26
My case was that I did not have direct access to EF context from my MVC app.
So if you are using some kind of repository for entity persistence it could be appropiate to simply detach explicitly loaded entity and then set binded EntityState to Modified.
Sample (abstract) code:
MVC
Repository
@Eckert 2017-12-15 18:34:24
This worked for me, although i didn't bother using a repository to reference the context entity states.
@Celdor 2015-01-30 13:52:06
I have added this answer only because the problem is explained based on more complex data pattern and I found it hard to understand here.
I created a fairly simple application. This error occurred inside Edit POST action. The action accepted ViewModel as an input parameter. The reason for using the ViewModel was to make some calculation before the record was saved.
Once the action passed through validation such as
if(ModelState.IsValid)
, my wrongdoing was to project values from ViewModel into a completely new instance of Entity. I thought I'd have to create a new instance to store updated data and then saved such instance.What I had realised later was that I had to read the record from database:
and updated this object. Everything works now.
@Luke Puplett 2015-01-14 11:41:03
I thought I'd share my experience on this one, even though I feel a bit silly for not realising sooner.
I am using the repository pattern with the repo instances injected into my controllers. The concrete repositories instantiate my ModelContext (DbContext) which lasts the lifetime of the repository, which is
IDisposable
and disposed by the controller.The issue for me was that I have a modified stamp and row version on my entities, so I was getting them first in order to compare with the inbound headers. Of course, this loaded and tracked the entity that was subsequently being updated.
The fix was simply to change the repository from newing-up a context once in the constructor to having the following methods:
This allows the repository methods to re-new their context instance upon each use by calling
GetDbContext
, or use a previous instance if they so desire by specifying true.@Kaspars Ozols 2014-04-21 19:04:35
It seems that entity you are trying to modify is not being tracked correctly and therefore is not recognized as edited, but added instead.
Instead of directly setting state, try to do the following:
Also, I would like to warn you that your code contains potential security vulnerability. If you are using entity directly in your view model, then you risk that somebody could modify contents of entity by adding correctly named fields in submitted form. For example, if user added input box with name "A.FirstName" and the entity contained such field, then the value would be bound to viewmodel and saved to database even if the user would not be allowed to change that in normal operation of application.
Update:
To get over security vulnerability mentioned previously, you should never expose your domain model as your viewmodel but use separate viewmodel instead. Then your action would receive viewmodel which you could map back to domain model using some mapping tool like AutoMapper. This would keep you safe from user modifying sensitive data.
Here is extended explanation:
http://www.stevefenton.co.uk/Content/Blog/Date/201303/Blog/Why-You-Never-Expose-Your-Domain-Model-As-Your-MVC-Model/
@Chris Ciszak 2014-04-21 19:31:03
Hi Kaspars, thanks for input. The Attach method throws the same errors as mention in my question. The problem is that canUserAccessA() function loads entity as well as CodeCaster noticed above. But saying that I am very interested in your suggestion wtih regards to security. Could you suggest what should I do to prevent such behaviour?
@Kaspars Ozols 2014-04-22 09:48:14
Updated my answer with additional info about how to prevent security vulnerability.