Domanda

Sto quindi utilizzando Fluent NHibernate e la sua caratteristica automapping per mappare le seguenti classi semplificate 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; }       
}

Sto quindi sovrascrivendo la seguente mappatura per impostare in modo esplicito non a cascata dalla pagina web per WebpageType:

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

Per tutti i lettori pur NHibernate, qui le mappature XML prodotto da fluente:

<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>

Il problema arriva quando prova che gli aggiornamenti non cascata a WebpageType tramite pagina web, in fondo lo fanno !!

Ho il seguente test:

    [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);
    }

La prova di cui sopra è avvolto in una transazione globale.

Il test ha esito negativo e NHibernate fa eseguire un aggiornamento per il nome del relativo WebpageType. Le cascate eliminazione e il salvataggio (creare nuovi) funzionano correttamente e non a cascata.

Ho forse missunderstood a cascata e / o c'è un problema con la mia logica / test.

Qualsiasi aiuto / consiglio è apprezzato. Grazie.

È stato utile?

Soluzione

Se si sta tentando di fermare la vostra applicazione di modificare accidentalmente le proprietà su WebPageType, penso che sarebbe più facile e più sicuro per raggiungere questo obiettivo contrassegnando WebPageType come ReadOnly nella mappatura. Allora non sarà necessario per proteggere tramite la gestione a cascata in tutte le sue associazioni.

Altri suggerimenti

Credo che questo sia un fraintendimento di cosa significa a cascata.

Nel tuo esempio, NHibernate aggiornerà la proprietà Name di voi WebPageType non importa ciò che si imposta a cascata a. Se ci pensate, come sarebbe la biblioteca NHibernate dire se si sta manipolando il valore della proprietà utilizzando l'associazione dall'istanza pagina web, o se è fatto "direttamente"?

Le impostazioni per cascata in NHibernate racconta come le associazioni tra le entità devono essere maneggiati, non come il valore reale all'interno di ogni entità viene gestito. Ad esempio, è possibile impostare eliminare cascata, che cancellerà automaticamente le entità associate quando l'entità stessa viene eliminato.

Cose blog post potrebbe rendere le cose un po 'più chiaro, o almeno di lavoro come una sorta di riferimento: http://ayende.com/Blog/archive/2006/12/02/NHibernateCascadesTheDifferentBetweenAllAlldeleteorphansAndSaveupdate.aspx

Che cosa fa il repository fare? Assicurarsi che non viene eseguito un saveOrUpdate sul webpagetype. Se non lo è, allora non vedo alcuna spiegazione ovvia per questo comportamento.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top