问题
I have a document library site and would like to send an email when a document object is edited, containing a summary of the changes.
The database interaction is Code First Entities Framework using DBContext
Here is what I have so far:
    [HttpPost]
    public ActionResult Edit(Document document, bool sendEmail, string commentsTextBox)
    {
        if (ModelState.IsValid)
        {
            docsDB.Entry(document).State = EntityState.Modified;
            foreach (string propertyName in docsDB.Entry(document).OriginalValues.PropertyNames)
            {
                var OriginalValue = docsDB.Entry(document).OriginalValues.GetValue<object>(propertyName);
                var NewValue = docsDB.Entry(document).CurrentValues.GetValue<object>(propertyName);
                if (!OriginalValue.Equals(NewValue))
                {
                    //capture the changes
                }
            }
            docsDB.SaveChanges();
            if (sendEmail)
            {
               //sends email
            }
            return RedirectToAction("Index");
        }
However, OriginalValue and NewValue are always the same -- the values of the update.
Is there any way, short of something hacky like writing to a file, to capture the state of the document before the POST?
回答1:
For the comparison of the updated properties with the values in the database you must reload the document from the database. You can try it this way:
[HttpPost]
public ActionResult Edit(Document document, bool sendEmail,
    string commentsTextBox)
{
    if (ModelState.IsValid)
    {
        var documentInDB = docsDB.Documents.Single(d => d.Id == document.Id);
        docsDB.Entry(documentInDB).CurrentValues.SetValues(document);
        foreach (string propertyName in docsDB.Entry(documentInDB)
                                        .OriginalValues.PropertyNames)
        {
            var OriginalValue = docsDB.Entry(documentInDB)
                                .OriginalValues.GetValue<object>(propertyName);
            var NewValue = docsDB.Entry(documentInDB)
                           .CurrentValues.GetValue<object>(propertyName);
            if (!OriginalValue.Equals(NewValue))
            {
                //capture the changes
            }
        }
        docsDB.SaveChanges();
        if (sendEmail)
        {
           //sends email
        }
        return RedirectToAction("Index");
    }
    // ...
}
    来源:https://stackoverflow.com/questions/9135340/recording-changed-values-with-dbcontext-entry-originalvalues-and-entry-newvalues