3

然后我使用 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 读者,这里是 fluent 生成的 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 确实对相关 WebpageType 的名称执行了更新。删除和保存(创建新)级联工作正常,不会级联。

我是否误解了级联和/或我的逻辑/测试有问题。

任何帮助/建议表示赞赏。谢谢。

4

3 回答 3

4

如果您试图阻止您的应用程序意外更改 WebPageType 上的属性,我认为通过在映射中将 WebPageType 标记为 ReadOnly 来实现这一点会更容易、更安全。然后,您无需通过处理其所有关联中的级联来保护它。

于 2010-01-11T20:58:46.110 回答
3

我认为这是对级联含义的误解。

在您的示例中,无论您将级联设置为什么,NHibernate 都会更新您 WebPageType 的 Name 属性。如果您考虑一下,NHibernate 库将如何判断您是使用来自 WebPage 实例的关联来操作属性的值,还是“直接”完成?

NHibernate 中的级联设置告诉了应该如何处理实体之间的关联,而不是如何处理每个实体内部的实际值。例如,可以设置删除级联,当实体本身被删​​除时,会自动删除关联的实体。

Things博客文章可能会让事情变得更清晰,或者至少可以作为某种参考:http ://ayende.com/Blog/archive/2006/12/02/NHibernateCascadesTheDifferentBetweenAllAlldeleteorphansAndSaveupdate.aspx

于 2010-01-11T21:14:00.163 回答
0

您的存储库是做什么的?确保它不在网页类型上运行 saveorupdate。如果不是,那么我看不到这种行为有任何明显的解释。

于 2010-01-09T17:33:03.040 回答