nhibernate - tg_op - trigger postgresql
¿Cómo inserto o actualizo(o sobrescribo) un registro usando NHibernate? (5)
Necesito escribir una fila en la base de datos independientemente de si ya existe o no. Antes de usar NHibernate esto se hizo con un procedimiento almacenado. El procedimiento intentaría una actualización y si no se modificaron las filas, se volvería a colocar en una inserción. Esto funcionó bien porque a la aplicación no le importa si el registro existe.
Con NHibernate, las soluciones que he encontrado requieren cargar la entidad y modificarla, o eliminar la entidad para que se pueda insertar la nueva. La aplicación tiene que importar si el registro ya existe. ¿Hay alguna manera de evitar eso?
¿Importa el Id?
Id asignado
El objeto tiene una palabra clave como un ID asignado y es la clave principal en la tabla.
Entiendo que SaveOrUpdate () llamará al método Save () o Update () según corresponda según el Id. Al usar una identificación asignada, esto no funcionará porque la identificación no es un valor no guardado. Sin embargo, un campo Version o Timestamp podría usarse como un indicador en su lugar. En realidad, esto no es relevante porque esto solo refleja si el objeto en la memoria se ha asociado con un registro en la base de datos; no indica si el registro existe o no en la base de datos.
ID generado
Si la identificación asignada fuera realmente la causa del problema, podría usar una identificación generada en lugar de la palabra clave como clave principal. Esto evitaría el problema de inserción / actualización de NHibernate, ya que de hecho siempre se insertaría. Sin embargo, aún debo evitar palabras clave duplicadas. Con un índice único en la columna de palabra clave, generará una excepción para una palabra clave duplicada incluso si la clave principal es diferente.
¿Otro enfoque?
Tal vez el problema no es realmente con NHibernate, sino la forma en que esto se modela. A diferencia de otras áreas de la aplicación, esto está más centrado en los datos que en los objetos. Es bueno que NHibernate facilite la lectura / escritura y elimine los procedimientos almacenados. Pero el deseo de simplemente escribir sin tener en cuenta los valores existentes no encaja bien con el modelo del modelo de identidad de un objeto. ¿Hay una mejor manera de abordar esto?
Tu puedes hacer
Obj j = session.get(Object.class(), id);
if (j != null)
session.merge(myObj);
else
session.saveOrUpdate(myObj);
Use el método session.SaveOrUpdate (object).
llame a hibernate.saveOrUpdate () que verificará si el objeto está en la base de datos, actualícelo si es y guarde (es decir, insértelo) si no lo está.
Normalmente, NHibernate puede confiar en el valor no guardado para determinar si debe insertar o crear la entidad. Sin embargo, dado que está asignando la ID, a NHibernate parece que su entidad ya se ha conservado. Por lo tanto, debe confiar en versionar su objeto para que NHibernate sepa que es un objeto nuevo. Consulte el siguiente enlace sobre cómo versionar su entidad:
Estoy usando
public IList<T> GetByExample<T>(T exampleInstance)
{
return _session.CreateCriteria(typeof(T))
.Add(Example.Create(exampleInstance))
.List<T>();
}
public void InsertOrUpdate<T>(T target)
{
ITransaction transaction = _session.BeginTransaction();
try
{
var res=GetByExample<T>(target);
if( res!=null && res.Count>0 )
_session.SaveOrUpdate(target);
else
_session.Save(target);
transaction.Commit();
}
catch (Exception)
{
transaction.Rollback();
throw;
}
finally
{
transaction.Dispose();
}
}
pero el método FindByExample devuelve todos los objetos igual que los objetos con la identificación exacta ¿qué sugieres? como solo tengo el objeto como parámetro, no tengo acceso a su campo ID específico, así que no puedo usar session.get(Object.class(), id);