NHibernate agrega una columna no asignada en el interceptor
-
05-07-2019 - |
Pregunta
Estoy intentando guardar una entidad asignada usando NHibernate pero mi inserción en la base de datos falla porque la tabla subyacente tiene una columna que no permite nulos y NO se asigna en mi objeto de dominio. La razón por la que no se asigna es porque la columna en cuestión admite una aplicación heredada y no tiene relevancia para mi aplicación, por lo que me gustaría no contaminar mi entidad con la propiedad heredada.
Sé que podría usar un campo privado dentro de mi clase, pero esto todavía me parece desagradable. He leído que puedo usar un interceptor NHibernate y anular el método OnSave () para agregar en la nueva columna justo antes de que se guarde mi entidad. Esto está resultando difícil ya que no puedo averiguar cómo agregar una instancia de Nhibernate.type.IType al parámetro de tipos de OnSave de mi interceptor.
Mi Entidad se parece a esto:
public class Client
{
public virtual int Id { get; set; }
public virtual int ParentId { get; set; }
public virtual string Name { get; set; }
public virtual string Phone { get; set; }
public virtual string Email { get; set; }
public virtual string Url { get; set; }
}
Y mi interceptor
public class ClientInterceptor : EmptyInterceptor
{
public override bool OnSave(object entity, object id, object[] state, string[] propertyNames, NHibernate.Type.IType[] types)
{
if (entity is Client)
{
/*
manually add the COM_HOLD column to the Client entity
*/
List<string> pn_list = propertyNames.ToList();
pn_list.Add("COM_HOLD");
propertyNames = pn_list.ToArray();
List<Object> _state = state.ToList();
_state.Add(false);
state = _state.ToArray();
//somehow add an IType to types param ??
}
return base.OnSave(entity, id, state, propertyNames, types);
}
}
¿Alguien tiene alguna idea sobre cómo hacer esto correctamente?
Solución
No puedo asegurarlo ya que nunca hice esto (como Stefan, también prefiero agregar una propiedad privada), pero ¿puedes agregar un NHibernate.Type.BooleanType
a la matriz types
?
List<IType> typeList = types.ToList();
typeList.Add(new BooleanType());
types = typesList.ToArray();
EDIT
Sí, parece que tienes razón; los tipos tienen un constructor interno
. Hice algunas excavaciones y encontré TypeFactory
:
Las aplicaciones deben usar estática Métodos y constantes en NHibernate.NHibernateUtil si el Por defecto, IType es lo suficientemente bueno. Por ejemplo, el TypeFactory sólo debe ser utilizado cuando la Cadena debe tener una longitud de 300 en lugar de 255. En este punto NHibernate.String no le proporciona el tipo de información correcto. En su lugar, use TypeFactory.GetString (300) y mantenga una variable local que contiene una referencia al IType.
Por lo que parece que lo que quieres es NHibernateUtil
:
Proporciona acceso a la gama completa de Tipos de NHibernate incorporados. Yo tecleo Se pueden usar instancias para unir valores. para consultar parámetros. También una fábrica para nuevos blobs y clobs.
typeList.Add(NHibernateUtil.Boolean);
Otros consejos
Personalmente no lo haría tan complicado. Yo agregaría la propiedad privada y le asignaría un valor predeterminado - terminado. También podría considerar un valor predeterminado en la base de datos, entonces no necesita hacer nada más.
private virtual bool COM_HOLD
{
get { return false; }
set { /* make NH happy */ }
}
Antes de escribir un interceptor para eso, consideraría escribir un disparador de base de datos. Porque con el Interceptor estás " contaminando " su capa de acceso a datos. podría hacerlo inestable y podría tener problemas extraños.