Pergunta

Estou em seguida, usando Fluent NHibernate e sua característica mapeamento automático para mapear as seguintes classes POCO simplificadas:

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

Estou em seguida, substituindo o seguinte mapeamento para definir explicitamente nenhuma cascata da página Web para WebpageType:

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

Para todos os leitores NHibernate pur, aqui estão os mapeamentos XML produzidos pela 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>

O problema surge quando eu testar se as atualizações não cascata para WebpageType via página web, basicamente, eles fazem !!

Eu tenho o seguinte teste:

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

O teste acima é envolto em uma transação global.

O teste falha e NHibernate faz executar uma atualização para o Nome do WebpageType relacionado. As cascatas apagar e guardar (criar novo) funcionam corretamente e não fazer em cascata.

Have I missunderstood cascata e / ou há um problema com a minha lógica / teste.

Qualquer ajuda / aconselhamento é apreciado. Obrigado.

Foi útil?

Solução

Se você está tentando parar a sua aplicação alterem acidentalmente propriedades em WebPageType, eu acho que seria mais fácil e mais seguro para atingir esse marcando WebPageType como ReadOnly no mapeamento. Então você não vai precisar para protegê-lo através de manipulação em cascata em todas as suas associações.

Outras dicas

Eu acho que este é um mal-entendido do que em cascata meios.

No seu exemplo, NHibernate irá atualizar a propriedade de nome de vocês não WebPageType independentemente da configuração em cascata para. Se você pensar sobre isso, como é que a biblioteca tell NHibernate se você está manipulando o valor da propriedade usando a associação da instância página web, ou se ele é feito "directamente"?

As definições para cascata em NHibernate conta como associações entre entidades devem ser manipulados, e não como o valor real dentro de cada entidade é tratado. Por exemplo, você pode definir exclusão em cascata, o que excluirá automaticamente entidades associadas quando a entidade em si é excluído.

As coisas blog pode tornar as coisas um pouco mais claro, ou pelo menos o trabalho como uma espécie de referência: http://ayende.com/Blog/archive/2006/12/02/NHibernateCascadesTheDifferentBetweenAllAlldeleteorphansAndSaveupdate.aspx

O que o seu repositório de fazer? Certifique-se de não executar um saveOrUpdate na webpagetype. Se não for, então eu não vejo qualquer explicação óbvia para este comportamento.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top