1

我正在开发一个更大的应用程序,它试图遵循分层架构模式。在 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 可能保留为 header,但 Detail 会,例如,由 DetailDbo 和 RelevantObjectDbo 的部分组成。然后应用程序在实体上做它的事情 - 发生一些细节转换,现在需要持久化。

假设我只影响了 Detail 实体中需要进入 Detail 表的部分,并且不以任何方式影响 RelevantObject 表。考虑模型的方式可能是错误的,但我们还需要对持久化的工作原理进行实际操作。所以,比如说,我只想让 NHibernate 更新 Detail 表而不“接触” RelevantObject 表上的任何内容。实际上,这正是问题所在:我如何实现这一目标?

当然,在现实中,DB 模型更大更复杂,应用程序逻辑也是如此。可能有一部分 BL 根本不处理数据的 RelevantObject 部分,因此即使 DBO 完全从数据库加载,也不是所有数据都能进入应用程序模型。但是要将数据持久化回数据库 - 似乎我需要完全水合数据库模型,但这并不总是实用的。那么,我们如何指示 NHibernate “不接触” RelevantObject——换句话说,不更新 dbo.Detail.RelevantObjectId?

我尝试将不同的 Cascade 选项应用于 DetailDbo.RelevantObject 属性,但如果它保持为空,NHibernate 总是希望将 RelevantObjectId 设置为 NULL - 我想,这是正确的。

我不明白如何在不必通过所有关联加载和保存数据库的一半的情况下对与我的 BL 的“部分”相关的数据进行更改。

谢谢!

4

1 回答 1

0

您如何执行这些更新?如果您没有在RelevantObjectNHibernate 上修改任何内容,则不会发送该表的更新。例如:

var header = session.Get<HeaderDbo>(1);
header.Details.First().DetailName = "Whatever";
session.Flush();

不应导致向RelevantObject表发出更新。

于 2017-12-13T21:28:42.897 回答