NHibernate级联无仍在更新相关实体
然后,我使用Fluent NHibernate及其自动映射功能映射以下简化的POCO类:NHibernate级联无仍在更新相关实体,nhibernate,fluent-nhibernate,cascade,many-to-one,Nhibernate,Fluent Nhibernate,Cascade,Many To One,然后,我使用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 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; }
}
然后,我将覆盖以下映射,以显式设置从网页到WebpageType的无级联:
public class WebpageMap : IAutoMappingOverride<Webpage>
{
public void Override(AutoMapping<Webpage> mapping)
{
mapping.References(w => w.WebpageType).Cascade.None();
}
}
上述测试包装在一个全局事务中
测试失败,NHibernate会对相关WebPagetType的名称执行更新。“删除”和“保存”(创建新)级联工作正常,不级联
我是否理解错了级联和/或我的逻辑/测试有问题
欢迎提供任何帮助/建议。谢谢。您的存储库是做什么的?确保它没有在WebGetType上运行saveorupdate。如果不是,那么我看不到任何明显的解释来解释这种行为。如果您试图阻止您的应用程序意外更改WebPagetType上的属性,我认为通过在映射中将WebPagetType标记为只读来实现这一点会更容易、更安全。那么您就不需要通过处理所有关联中的级联来保护它。我认为这是对级联含义的误解 在您的示例中,无论您将级联设置为什么,NHibernate都将更新WebPagetType的Name属性。仔细想想,NHibernate库如何判断您是使用网页实例的关联操作属性值,还是直接操作属性值 NHibernate中的级联设置告诉我们应该如何处理实体之间的关联,而不是如何处理每个实体内的实际值。例如,您可以设置delete cascading,该选项将在删除实体本身时自动删除关联的实体
Things blog post可能会让事情变得更清楚,或者至少可以作为某种参考:嗨,Brian,不,我的存储库只是保存网页。嗨,Liedman,我明白你的意思。但是,如果我只保存网页对象,为什么NH还要保存与WebpageType的多对一关联?这不是一种级联保存吗?这是关于NHibernate如何工作的最常见错误之一。在NHibernate中,对持久对象的更改(即使用查询、get/load或使用save将实例从DB加载到ISession中)将自动保存到数据库中(除非回滚事务)。从文档中可以看出:“事务性持久实例(即ISession加载、保存、创建或查询的对象)可以由应用程序操作,并且在刷新ISession时,对持久状态的任何更改都将被持久化”(除非您另有指定,否则刷新i自动)。谢谢Noel,我将尝试:)
<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>
[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);
}