Reputation: 11
I have a scenario that could not find the solution for it and need some help How can I achieve this, I’d like to get current record for the client modify it and instead of update I’d like to add the new record to table for historical change information
client c = new client();
using (DBEntities db = new DBEntities())
{
// get current records in the client table for client
IQueryable<client> co = from p in db.client where p.CUS_NUMBER == scd.cus_number && p.isCurrent == true select p;
c = co.First();
//update email and and address
c.EMAIL = Helper.CleanInput("[email protected]");
c.ADDRESS = Helper.CleanInput("123 Sheppard");
//instead of updating current record I'd like to add new record to the table to keep historical changes
db.AddToclient(c);
db.SaveChanges();
//I get error that
//An object with the same key already exists in the ObjectStateManager.
//The existing object is in the Modified state. An object can only be added to
//the ObjectStateManager again if it is in the added state.
An object with the same key already exists in the ObjectStateManager. The existing object is in the Modified state. An object can only be added to the ObjectStateManager again if it is in the added state.
Upvotes: 1
Views: 7203
Reputation: 2338
In Entity Framework, all objects retrieved from database by default are tracked by ObjectContext instance. Entity Framework internally maps all objects being tracked by his Key. This pattern is called Identity Map. This means that there will be only one instance of an entity per key. So, you don't need to call Add again, since the entity is already on EF map. You just need call SaveChanges to persist modified entities.
In your case you are:
1 - Creating a new instance of EF ObjectContext;
2 - Retrieving entities in your LINQ query;
3 - Changing values of properties of the retrieved entity;
4 - Adding again to the ObjContext; //error!
5 - Calling SaveChanges()
Step 4 is not necessary because the ObjectContext already knows about the retrieved objects.
Upvotes: 0
Reputation: 9593
The reason db.AddToclient(c);
gives the error is because this object is being tracked by the object context, by possibly being in the database.
The best way to accomplish what you are trying to do is something like the following:
var newClient = new client()
{
EMAIL = Helper.CleanInput("[email protected]"),
ADDRESS = Helper.CleanInput("123 Sheppard"),
};
db.AddToclient(newClient);
db.SaveChanges();
Upvotes: 0
Reputation: 1036
It's look like you are adding same row to database and error is coming due to addition of same row again having same primary key which DB will not allow.
Try to add new row and make another table that keeps Historical information of old row and a reference as foreign key. You can add a boolean field that keep information regarding deletion let It is IsDeleted.
Hope It will Help Thanks
Upvotes: 0
Reputation: 13351
remove this code db.AddToclient(c);
,rest all is fine,You are already accessing the object by its reference so no need to add it again.It'll get modified when you call savechanges()
or use cloning if you want to add new object c = co.First().Clone();
Upvotes: 1