Мы используем NHibernate в нашем проекте и подключаемся к событиям перед обновлением / вставкой / удалением, чтобы провести некоторый аудит.
Мы хотим проверять каждую сущность в своей собственной таблице аудита, которая имеет ту же схему, что и исходная таблица (возможно, с помощью операции аудита, такой как «Обновление», «Вставка» и т. Д.).
Я посмотрел на unHAddins, которые будут автоматически генерировать триггеры, но кажется, что они отбрасывают и воссоздают таблицы аудита, когда вы вносите изменения в основную таблицу, которые мы не можем принять, нам также нужна некоторая настраиваемая логика, чтобы мы могли проверять запись только при определенных обстоятельствах ее фактических свойств (свойства, которые нас интересуют, являются частью базового класса для всех наших объектов).
Чтобы сделать это просто, я решил, что могу просто расширить существующие классы домена и затем определить новое отображение Nhibernate для этих расширенных классов.
Например:
У нас есть класс Instrument
public class Instrument : BaseObject, IAuditable
{
public virtual string Title { get; set; }
public virtual IList<Control> Controls { get; set; }
public virtual CouncilRegion Region { get; set; }
public Type GetAuditType()
{
return typeof (InstrumentAudit);
}
Я определил интерфейс Iauditable, чтобы мы могли выяснить, какой класс является классом аудита для любого объекта Iauditable.
Аудиторский класс выглядит следующим образом
public class InstrumentAudit : Instrument
{}
У него нет дополнительной функциональности, это просто хак, который позволяет нам сопоставить его с нашей таблицей аудита в NHibernate.
Похоже, это сработает, но проблема возникает при попытке обработать события NHibernate
public class EventListener: IPreInsertEventListener, IPreUpdateEventListener, IPreDeleteEventListener
{
private readonly IAuditLogger _logger = new AuditLogger();
public bool OnPreInsert(PreInsertEvent e)
{
Audit(e.Entity as BaseObject, AuditType.Insert);
return false;
}
}
private void Audit(object entity, AuditType auditType)
{
if(entity is IAuditable && entity is BaseObject)
{
_logger.Log(entity, auditType);
}
}
e.Entity дано мне как объект.
public class AuditLogger : IAuditLogger
{
public void Log(object entity, AuditType auditType)
{
if (entity is IAuditable && entity is BaseObject)
{
var auditObject = entity as IAuditable;
Type type = auditObject.GetAuditType();
var x = (type) auditObject;
DataRepository.Instance.Save(x);
}
}
}
Выше приведен код, над которым я хотел бы поработать, в основном я знаю, что этот объект должен проверяться, и это один из моих базовых объектов, поэтому я хотел бы преобразовать его в подтип объекта аудита и передать это чтобы спасти.
К сожалению, не похоже, что вы можете приводить к переменной, это должен быть фактический тип, есть ли в любом случае это так, чтобы я мог приводить или преобразовывать объект в его тип "аудита", не прибегая к конструкторам / конвертерам для каждого типа аудита, который принимает свой базовый тип и сохраняет свойства?