然后我使用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会对相关网页类型的名称执行更新。删除和保存(创建新)级联正常工作,不会级联。
我是否错过了对cascade的理解和/或我的逻辑/测试是否存在问题。
感谢任何帮助/建议。感谢。
答案 0 :(得分:3)
如果您试图阻止您的应用程序意外更改WebPageType上的属性,我认为通过在映射中将WebPageType标记为ReadOnly来实现此目标会更容易,更安全。然后,您不需要通过处理其所有关联中的级联来保护它。
答案 1 :(得分:3)
我认为这是对级联意味着什么的误解。
在你的例子中,无论你设置级联到什么,NHibernate都会更新你的WebPageType的Name属性。如果你考虑一下,NHibernate库如何使用WebPage实例中的关联来操作属性的值,或者它是否“直接”完成?
NHibernate中级联的设置告诉我们应该如何处理实体之间的关联,而不是如何处理每个实体内部的实际值。例如,您可以设置删除级联,当实体本身被删除时,它将自动删除关联的实体。
博客文章可能会让事情变得更清晰,或者至少可以作为某种参考:http://ayende.com/Blog/archive/2006/12/02/NHibernateCascadesTheDifferentBetweenAllAlldeleteorphansAndSaveupdate.aspx
答案 2 :(得分:0)
您的存储库有什么作用?确保它没有在网页类型上运行saveorupdate。如果不是,那么我没有看到任何明显的解释这种行为。