2009-04-23 26 views
20

Estoy un poco confundido sobre cómo funciona Flush (y NHibernate.ISession) en NHibernate.NHibernate Flush-- ¿Cómo funciona?

Desde mi código, parece que cuando guardé un objeto usando ISession.Save(entity), el objeto se puede guardar directamente en la base de datos.

Sin embargo, cuando actualizo y me opongo usando ISession.SaveOrUpdate(entity) o ISession.Update(entity), el objeto en la base de datos no se actualiza --- Necesito llamar al ISession.Flush para actualizarlo.

El procedimiento de cómo puedo actualizar el objeto es el siguiente:

  1. obtener el objeto de la base de datos mediante el uso de ISession.Get(typeof(T), id)
  2. Cambiar la propiedad del objeto, por ejemplo, myCar.Color="Green"
  3. cometerlo de nuevo a la base de datos mediante el uso de ISession.Update(myCar)

el myCar no se actualiza la base de datos. Sin embargo, si llamo después al ISession.Flush, entonces se actualiza.

Cuándo utilizar Flush, y cuándo no utilizarlo?

+0

posible duplicado de [NHibernate ISession Flush: dónde y cuándo usarlo, y por qué?] (Http://stackoverflow.com/questions/43320/nhibernate-isession-flush-where-and-when-to -use-it-and-why) – sleske

Respuesta

28

En muchos casos, usted no tiene que preocuparse cuando los rubores de NHibernate.

Solo necesita llamar a flush si creó su propia conexión porque NHibernate no sabe cuándo se compromete con ella.

Lo que es realmente importante para usted es la transacción. Durante la transacción, está aislado de otras transacciones, es decir, siempre ve sus cambios cuando lee desde la base de datos, y no ve otros cambios (a menos que estén comprometidos). Por lo tanto, no tiene que preocuparse cuando NHibernate actualice los datos en la base de datos a menos que estén comprometidos. No es visible para nadie de todos modos.

NHibernate vuelca si

  • se llama a comprometerse
  • antes de consultas para asegurar que se filtra por el estado actual en la memoria
  • cuando se llama a ras

Ejemplo:

using (session = factory.CreateSession()) 
using (session.BeginTransaction()) 
{ 
    var entity = session.Get<Entity>(2); 
    entity.Name = "new name"; 

    // there is no update. NHibernate flushes the changes. 

    session.Transaction.Commit(); 
    session.Close(); 
} 

La entidad se actualiza en commit. NHibernate ve que su sesión está sucia y borra los cambios en la base de datos. Necesita actualizar y guardar solo si realizó los cambios fuera de la sesión. (Esto significa con una entidad separada, que es una entidad que no es conocida por la sesión).


Notas sobre el rendimiento: ras no sólo realiza las sentencias SQL necesarias para actualizar la base de datos. También busca cambios en la memoria. Dado que no hay indicador sucio en POCO, necesita comparar cada propiedad de cada objeto en la sesión con su primer nivel de caché. Esto puede convertirse en un problema de rendimiento cuando se realiza con demasiada frecuencia. Hay un par de cosas que puede hacer para evitar problemas de rendimiento:

  • No echar en bucles
  • Evitar objetos serializados (se requiere la serialización para comprobar si hay cambios)
  • Uso read-only entities cuando sea apropiado
  • Establezca mutable = false cuando corresponda
  • Al usar tipos personalizados en las propiedades, implemente métodos equivalentes eficientes
  • Deshabilite cuidadosamente el lavado automático cuando esté seguro de que y Sabes lo que estás haciendo.
+0

Gracias, pero cuando actualizo un objeto en la base de datos, ¿esto significa que creo mi propia transacción? O bien, ¿por qué debo llamar a Flush para actualizar la base de datos? – Graviton

+1

Tuve que arreglarlo: necesita enjuagarse cuando creó su propia conexión. NHibernate crea una conexión para usted si llama a CreateSession, pero puede proporcionarle su propia conexión ADO.NET. Usualmente no necesitas esto No necesita llamar a color si no lo hace. –

6

NHibernate solo realizará declaraciones SQL cuando sea necesario. Pospondrá la ejecución de sentencias de SQL el mayor tiempo posible.

Por ejemplo, cuando guarda una entidad que tiene una identificación asignada, es probable que posponga la ejecución de la instrucción INSERT. Sin embargo, cuando inserta una entidad que tiene una identificación de auto incremento, por ejemplo, NHibernate necesita INSERTAR la entidad directamente, ya que debe conocer la identificación que se le asignará a esta entidad.

Cuando llama explícitamente a flush, NHibernate ejecutará las sentencias SQL que son necesarias para los objetos que se han cambiado/creado/eliminado en esa sesión.

Flush

+0

siempre que el enlace no funcione. Dice "Este contenido ya no está disponible en Knol". – N30

+0

@ N30: ​​Acabo de arreglar el enlace. –

Cuestiones relacionadas