Pregunta

entonces yo estoy usando NHibernate Fluido y su característica automapping para asignar las clases de las siguientes simplificados POCO:

public class Webpage
{    
public virtual int Id { get; set; }    
public virtual string UrlIdentifier { get; set; }    
public virtual WebpageType WebpageType { get; set; }    
}

public class WebpageType
{    
public virtual int Id { get; set; }    
public virtual string Name { get; set; }       
}

Estoy a continuación, anulando la siguiente asignación para establecer explícitamente ninguna conexión en cascada de la página web a WebpageType:

public class WebpageMap : IAutoMappingOverride<Webpage>
{
    public void Override(AutoMapping<Webpage> mapping)
    {
        mapping.References(w => w.WebpageType).Cascade.None();    
    }
}

Para cualquier lector pur NHibernate, aquí están los mapeos XML producidos por fluidez:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true">
  <class xmlns="urn:nhibernate-mapping-2.2" name="EveryPage.Core.Domain.Webpage, EveryPage.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`Webpage`">
    <id name="Id" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" unsaved-value="0">
      <column name="Id" />
      <generator class="identity" />
    </id>
    <property name="UrlIdentifier" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="UrlIdentifier" />
    </property>
    <many-to-one cascade="none" class="EveryPage.Core.Domain.WebpageType, EveryPage.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="WebpageType">
      <column name="WebpageType_id" />
    </many-to-one>    
  </class>
</hibernate-mapping>


<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true">
  <class xmlns="urn:nhibernate-mapping-2.2" name="EveryPage.Core.Domain.WebpageType, EveryPage.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`WebpageType`">
    <id name="Id" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" unsaved-value="0">
      <column name="Id" />
      <generator class="identity" />
    </id>
    <property name="Name" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Name" />
    </property>
  </class>
</hibernate-mapping>

El problema viene cuando pruebo que las actualizaciones no caen en cascada a través de la página web WebpageType, básicamente, hacer !!

Tengo la siguiente prueba:

    [Test]
    public void Assert_SaveOrUpdate_On_Webpage_Does_Not_Cascade_Update_To_WebpageType()
    {
        // Get the existing webpage.
        webpage = _webpageRepository.Get("~/testwebpage1.aspx");

        // Update the WebpageType.
        const string webpageTypeName = "qwerty test";
        webpage.WebpageType.Name = webpageTypeName;

        // Save the changes.
        Assert.DoesNotThrow(() => _webpageRepository.SaveOrUpdate(webpage));

        // We need to flush the changes to the store for it to execute the changes.
        Assert.DoesNotThrow(() => NHibernateSession.Current.Flush());

        // Remove the webpage and tag from the level 1 cache so we force a trip to the store on our next check.
        NHibernateSession.Current.Evict(webpage);

        //  Check that the webpageType has not been updated.
        webpageType = _webpageTypeRepository.Get(webpageType.Id);
        Assert.AreNotEqual(webpageTypeName, webpageType.Name);
    }

El ensayo anterior se envuelve en una transacción global.

La prueba falla y NHibernate hace ejecutar una actualización en el Nombre de la WebpageType relacionada. Las cascadas de eliminar y guardar (crear nuevo) funcionan correctamente y no caen en cascada.

¿He Missunderstood cascada y / o hay un problema con mi lógica / prueba.

Cualquier ayuda / consejo se agradece. Gracias.

¿Fue útil?

Solución

Si usted está tratando de detener la aplicación de los cambios accidentales de propiedades en WebPageType, creo que sería más fácil y más seguro para lograr esto mediante el marcado de WebPageType como de sólo lectura en el mapeo. Entonces no tendrá que protegerla a través de la manipulación en cascada en todas sus asociaciones.

Otros consejos

Creo que esto es una mala interpretación de lo que significa la cascada.

En su ejemplo, NHibernate actualizará la propiedad Name de que WebPageType no importa lo que se propuso en cascada a. Si se piensa en ello, ¿cómo la biblioteca NHibernate saber si está manipulando el valor de la propiedad mediante la asociación de la instancia de página web, o si se hace "directamente"?

La configuración de conexión en cascada en NHibernate cuenta cómo se deben manejar las asociaciones entre entidades, no cómo se maneja el valor real dentro de cada entidad. Por ejemplo, se puede establecer eliminar en cascada, lo que eliminará automáticamente entidades asociadas cuando se elimina la propia entidad.

Cosas entrada del blog podría hacer las cosas un poco más claro, o al menos trabajar como una especie de referencia: http://ayende.com/Blog/archive/2006/12/02/NHibernateCascadesTheDifferentBetweenAllAlldeleteorphansAndSaveupdate.aspx

¿Qué hace su repositorio? Asegúrese de que no se ejecuta un saveOrUpdate en el webpagetype. Si no es así, entonces no veo ninguna explicación obvia para este comportamiento.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top