Hi There guys, Something has been confusing me. I created a method within my controller and I am calling it from Javascript Json/Ajax in my view page.
The purpose of this method is to set the Status of the DB field to Archive and then update my Audit table to denote the original data and new data.
But every time I call this method it inserts into the database with the same data, old and new are the same. (both having status of Archive where only the new record should have that and not the old).
Hope that makes sense and someone could help me out would be appreciated. Thanks!
[HttpPost]
public JsonResult ArchiveRecord(int id)
{
// Audit Process 1. Gather old values
var original_data = db.StudentRec.AsNoTracking().Where(P => P.ID == id).FirstOrDefault();
StudentRec NewRecord = original_data;
NewRecord.StudentStatus = "Archive";
db.Entry(NewRecord).State = EntityState.Modified;
db.SaveChanges();
Audit history = new Audit();
history.CreateAuditTrail(AuditActionType.Update, id, original_data, NewRecord);
return Json(id, JsonRequestBehavior.AllowGet);
}
You're creating references to the same object in memory (reference type). Simply create a new Audit record form the original
student by assigning the student properties values to the Audit entity (not sure what the name is). Similar to the following code.
[HttpPost]
public JsonResult ArchiveRecord(int id)
{
// Get the student
var student = db.StudentRec.Where(P => P.ID == id).FirstOrDefault();
//Set the audit fields from the student
AuditEntity audit = new AuditEntity()
{
StudentId = student.Id,
OtherField = student.OtherField
}
//Update the student entity
student.StudentStatus = "Archive";
//Save both records
db.Entry(AuditEntity).State = EntityState.Added;
db.SaveChanges();
return Json(id);
}
So you supposedly copied 'original' to 'new', but they are the same object, the 'original'. And then you changed data and state on 'new' that is really the 'orig'. And based on the primary ID of the object in 'new' that came from 'orig', it updated by ID
the data table record in the database the 'original' data in the table record.
Do you see what I am saying? The new and orig object have the same primary-key property that points back to the primacy-key ID of the record setting in the database table, which is the original data in the table record that is being updated by primary-key
ID.
If you find the post has answered your issue, then please mark post as 'answered'.
public void CreateAuditTrail(AuditActionType Action, int KeyFieldID, Object OldObject, Object NewObject)
Which will take the OldObject and newObject and save the info into the Audit table. That is why i was trying to create 2 objects, 1 that had all the data of the old one and then another with all the data except one updated field.
But i had to create a new object and all all the fields of the old object.
Is there a better way than this? Doesn't seem efficient. Thanks
var original_data = db.Student.AsNoTracking().Where(P => P.ID == id).FirstOrDefault();
Student audit = new TaskAuthorizationOCCB()
{
ID = id,
field_name = original_data.field_name,
...etc... for all the fields in the table for this object
};
Student newObj = original_data;
newObj.Status= "Archived";
db.Entry(newObj).State = EntityState.Modified;
db.SaveChanges();
Audit history = new Audit();
history.CreateAuditTrail(AuditActionType.Update, id, audit, newObj);
return Json(id);
Member
29 Points
86 Posts
Need help troubleshooting this Method.
Feb 26, 2019 08:37 PM|MVCNewbi3v|LINK
Hi There guys, Something has been confusing me. I created a method within my controller and I am calling it from Javascript Json/Ajax in my view page.
The purpose of this method is to set the Status of the DB field to Archive and then update my Audit table to denote the original data and new data.
But every time I call this method it inserts into the database with the same data, old and new are the same. (both having status of Archive where only the new record should have that and not the old).
Hope that makes sense and someone could help me out would be appreciated. Thanks!
All-Star
52201 Points
23284 Posts
Re: Need help troubleshooting this Method.
Feb 26, 2019 09:26 PM|mgebhard|LINK
You're creating references to the same object in memory (reference type). Simply create a new Audit record form the original student by assigning the student properties values to the Audit entity (not sure what the name is). Similar to the following code.
[HttpPost] public JsonResult ArchiveRecord(int id) { // Get the student var student = db.StudentRec.Where(P => P.ID == id).FirstOrDefault(); //Set the audit fields from the student AuditEntity audit = new AuditEntity() { StudentId = student.Id, OtherField = student.OtherField } //Update the student entity student.StudentStatus = "Archive"; //Save both records db.Entry(AuditEntity).State = EntityState.Added; db.SaveChanges(); return Json(id); }
The docs explain the same.
https://docs.microsoft.com/en-us/ef/ef6/saving/change-tracking/entity-state
Contributor
4873 Points
4123 Posts
Re: Need help troubleshooting this Method.
Feb 26, 2019 09:36 PM|DA924|LINK
You should only be dealing wit the ordinal object you got in context.
So you supposedly copied 'original' to 'new', but they are the same object, the 'original'. And then you changed data and state on 'new' that is really the 'orig'. And based on the primary ID of the object in 'new' that came from 'orig', it updated by ID the data table record in the database the 'original' data in the table record.
Do you see what I am saying? The new and orig object have the same primary-key property that points back to the primacy-key ID of the record setting in the database table, which is the original data in the table record that is being updated by primary-key ID.
Member
29 Points
86 Posts
Re: Need help troubleshooting this Method.
Feb 26, 2019 10:38 PM|MVCNewbi3v|LINK
I don't need to save both records thought.
What i need to do is be able to call the method
public void CreateAuditTrail(AuditActionType Action, int KeyFieldID, Object OldObject, Object NewObject)
Which will take the OldObject and newObject and save the info into the Audit table. That is why i was trying to create 2 objects, 1 that had all the data of the old one and then another with all the data except one updated field.
Member
29 Points
86 Posts
Re: Need help troubleshooting this Method.
Feb 26, 2019 10:39 PM|MVCNewbi3v|LINK
Yeah its what i figured after i looked in the audit db table where i was saving both object data to. They were the same.
Anyway to get the original object data "Student" and a new object data "Student" with the updated field?
Member
29 Points
86 Posts
Re: Need help troubleshooting this Method.
Feb 26, 2019 11:06 PM|MVCNewbi3v|LINK
I was able to accomplish what I wanted to do.
But i had to create a new object and all all the fields of the old object.
Is there a better way than this? Doesn't seem efficient. Thanks
All-Star
52201 Points
23284 Posts
Re: Need help troubleshooting this Method.
Feb 26, 2019 11:18 PM|mgebhard|LINK
Agreed but you have no choice due to the CreateAuditTrail method. Perhaps refactor the CreateAuditTrail method.
Member
29 Points
86 Posts
Re: Need help troubleshooting this Method.
Feb 27, 2019 01:42 PM|MVCNewbi3v|LINK
Thanks for the help guys. I'll mark this question answered for now :)