使用NHibernate

时间:2017-12-13 11:02:12

标签: c# nhibernate architecture fluent-nhibernate multi-layer

我正在开发一个更大的应用程序,它试图遵循分层架构模式。在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;相关的数据。通过所有关联,无需加载和保存我的数据库的一半。

谢谢!

1 个答案:

答案 0 :(得分:0)

您是如何进行这些更新的? 如果您没有在RelevantObject上修改任何内容,NHibernate将不会发送该表的更新。例如:

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

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