我正在开发一个更大的应用程序,它试图遵循分层架构模式。在DBAL上我使用流畅配置的NHibernate。数据库对象有时会包含以下关联:
public class HeaderDbo
{
public HeaderDbo()
{
Details = new List<DetailDbo>();
}
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual IList<DetailDbo> Details { get; set; }
}
public class DetailDbo
{
public virtual int Id { get; set; }
public virtual string DetailName { get; set; }
public virtual HeaderDbo Header { get; set; }
public virtual RelevantObjectDbo RelevantObject { get; set; }
}
public class RelevantObjectDbo
{
public virtual int Id { get; set; }
public virtual string RelevantText { get; set; }
}
映射如下:
public class HeaderDboMap : ClassMap<HeaderDbo>
{
public HeaderDboMap()
{
Table("Header");
Id(x => x.Id).Column("Id");
Map(x => x.Name);
HasMany(x => x.Details)
.Inverse()
.Cascade.All();
}
}
public class DetailDboMap : ClassMap<DetailDbo>
{
public DetailDboMap()
{
Id(x => x.Id).Column("Id");
Table("Detail");
Map(x => x.DetailName);
References(x => x.Header).Column("HeaderId");
References(x => x.RelevantObject).Column("RelevantObjectId")
.Cascade.SaveUpdate(); //??
}
}
public class RelevantObjectDboMap : ClassMap<RelevantObjectDbo>
{
public RelevantObjectDboMap()
{
Id(x => x.Id).Column("Id");
Table("RelevantObject");
Map(x => x.RelevantText);
}
}
现在,DBO映射到的应用程序域实体不一定一对一地反映数据库结构。例如,Header可能会保留标题,但是Detail会从DetailDbo和RelevantObjectDbo的部分形成。然后应用程序对实体做了一些事情 - 细节的某些转换发生了,现在需要持久化。
假设我只影响了Detail实体中需要进入Detail表的部分,并且不会以任何方式影响RelevantObject表。考虑模型可能是一种错误的方式,但我们也需要对持久性如何工作进行实践。所以,比如说,我想只让NHibernate更新Detail表而不用&#34;触摸&#34; RelevantObject表上的任何内容。这正是问题,实际上:我如何实现这一目标?
实际上,当然,DB模型更大更复杂,应用程序逻辑也是如此。可能有一部分BL根本不处理数据的RelevantObject部分,因此即使DBO完全从数据库加载,并非所有数据都可以进入应用程序模型。但是为了将数据保存回数据库 - 似乎我需要完全补充数据库模型并且它并不总是实用的。那么,我们如何指导NHibernate不要触摸&#34; RelevantObject - 换句话说,不更新dbo.Detail.RelevantObjectId?
我尝试将不同的Cascade选项应用于DetailDbo.RelevantObject属性,但如果它保持为null,则NHibernate总是希望将RelevantObjectId设置为NULL - 我想,这是理所当然的。
我不明白如何更改与我的&#34;部分&#34;相关的数据。通过所有关联,无需加载和保存我的数据库的一半。
谢谢!
答案 0 :(得分:0)
您是如何进行这些更新的?
如果您没有在RelevantObject
上修改任何内容,NHibernate将不会发送该表的更新。例如:
var header = session.Get<HeaderDbo>(1);
header.Details.First().DetailName = "Whatever";
session.Flush();
不应导致向RelevantObject
表发布更新。