У меня есть служба Windows, которая обрабатывает входные данные из xml-файлов. Мне нужно вставлять новые записи и обновлять существующие записи каждый раз, когда я получаю новый файл. Теперь мне нужно реализовать историю вставки \ обновления каждый раз после того, как произошла операция. Я должен поддерживать это в отдельной таблице, отображая старое значение и новое значение. Существуют ли какие-либо существующие методологии или методы для реализации этого проще, например, сравнение двух объектов и идентификация измененных полей. Пожалуйста, предоставьте любые предложения. Я использую Entityframework 5.0 и sql 2012.Вставка Обновление - сохранение истории объектов в ObjectContext
ответ
Существует несколько способов сделать это.
Использование перехватчиков API-интерфейсов персистентности. Например, инфраструктура JPA или Hibernate обеспечивает фасад вокруг операций вашего объекта, который запускается после операций DML в базе данных.
Слушатели событий: вы должны иметь возможность создавать прослушиватели событий внутри вашей инфраструктуры персистентности, которые будут запускаться и вставлять данные истории в ваши таблицы истории после каждой операции DML.
Триггеры базы данных. Это действительно один из самых простых способов хранения информации истории для данной строки/таблицы.
Надежда эти указатели помогают Anant
Специально для EF, вы можете переопределить DbContext.SaveChanges()
и перебрать DbContext.ChangeTracker.Entries()
. Каждая запись содержит текущие и оригинальные значения свойств объекта.
Класс My Entity был получен из ObjectContext
, который не предоставил ChangeTracker
для получения модифицированных значений. Однако для ObjectContext
мы можем получить измененные значения, используя DBContext.ObjectStateManager.GetObjectStateEntries(EntityState.Modified)
При необходимости вы можете использовать EntityState.Deleted
, EntityState.Added
. Ниже приводится пример внедрения
Entities DBContext = new Entities();
var d = DBContext.StudentTableName.Where(x => x.stname == "Stock").FirstOrDefault();
if(d!= null)
{
d.Id = "345";
DBContext.StudentTableName.ApplyCurrentValues(d);
//Need to Include Audit Logging before save, or can override save function.
var entrList = DBContext.ObjectStateManager.GetObjectStateEntries(EntityState.Modified);
foreach (var stateEntry in entrList)
{
var currentValues = stateEntry.CurrentValues;
var originalValues = stateEntry.OriginalValues;
var modifiedProperties = stateEntry.GetModifiedProperties();
foreach (string modifiedProperty in modifiedProperties)
{
var currentValue = currentValues.GetValue(currentValues.GetOrdinal(modifiedProperty));
var originalValue = originalValues.GetValue(originalValues.GetOrdinal(modifiedProperty));
if (!originalValue.Equals(currentValue))
{
//Perform the logging operation
}
}
}
// Audit Logging Performed
DBContext.SaveChanges();
}