NHibernate Cascade еще не обновляет связанный объект - PullRequest
3 голосов
/ 09 января 2010

Затем я использую Fluent NHibernate и его функцию автоматического сопоставления для отображения следующих упрощенных классов 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; }       
}

Затем я переопределяю следующее отображение, чтобы явно не устанавливать каскадное переключение с веб-страницы на тип веб-страницы:

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

Для любых чистых читателей NHibernate вот xml отображения, созданные свободно:

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

Проблема возникает, когда я проверяю, что обновления не касаются WebpageType через веб-страницу, в основном это происходит !!

У меня есть следующий тест:

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

Вышеупомянутый тест включен в глобальную транзакцию.

Тест не пройден, и NHibernate выполняет обновление имени связанного типа веб-страницы. Каскады удаления и сохранения (создания новых) работают корректно и не каскадируются.

Я неправильно понял каскад и / или возникла проблема с моей логикой / тестом.

Любая помощь / совет приветствуется. Спасибо.

Ответы [ 3 ]

3 голосов
/ 11 января 2010

Если вы пытаетесь предотвратить случайное изменение своего приложения в свойствах WebPageType, я думаю, что было бы проще и безопаснее добиться этого, пометив WebPageType как ReadOnly в отображении. Тогда вам не нужно будет защищать его, обрабатывая каскад во всех его ассоциациях.

3 голосов
/ 12 января 2010

Я думаю, что это неправильное понимание того, что означает каскадирование.

В вашем примере NHibernate обновит свойство Name вашего WebPageType независимо от того, на что вы установили каскадирование. Если подумать, как библиотека NHibernate скажет, манипулируете ли вы значением свойства, используя ассоциацию из экземпляра WebPage, или если это сделано «напрямую»?

Настройки каскадирования в NHibernate указывают, как должны обрабатываться ассоциации между сущностями, а не как обрабатывается фактическое значение внутри каждой сущности. Например, вы можете установить каскадное удаление, которое будет автоматически удалять связанные объекты при удалении самого объекта.

Вещи в блоге могут кое-что прояснить, или, по крайней мере, работать как некая ссылка: http://ayende.com/Blog/archive/2006/12/02/NHibernateCascadesTheDifferentBetweenAllAlldeleteorphansAndSaveupdate.aspx

0 голосов
/ 09 января 2010

Что делает ваш репозиторий? Убедитесь, что он не запускает saveorupdate для типа веб-страницы. Если это не так, я не вижу очевидного объяснения этому поведению.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...