NHibernate配置用于单向一对多关系

时间:2010-12-16 22:51:13

标签: nhibernate fluent-nhibernate one-to-many

我正在尝试建立如下关系。每个项都有一个或多个明细项:

public class Detail {
    public virtual Guid DetailId { get; set; }
    public virtual string Name { get; set; }
}
public class Master {
    public virtual Guid MasterId { get; set; }
    public virtual string Name { get; set; }
    public virtual IList<Detail> Details { get; set; }
}

和映射:

public class MasterMap : ClassMap<Master> 
{
    public MasterMap() 
    {
        Id(x => x.MasterId);
        Map(x => x.Name);
        HasMany(x => x.Details).Not.KeyNullable.Cascade.All();
    }
}
public class DetailMap : ClassMap<Detail> 
{
    public DetailMap() 
    {
        Id(x => x.Id);
        Map(x => x.Name);
    }
}

Master 数据库表是:

masterId   uniqueidentifier NOT NULL
name       nvarchar(max) NULL

明细是:

DetailId   uniqueidentifier NOT NULL
name       nvarchar(max) NULL
MasterId   uniqueidentifier NULL
foreign key (masterId) references [Master]

我真的不关心从细节回到主人的链接 - 换句话说,自己的细节对象对我的域层不感兴趣。他们将始终通过他们的主对象访问。

使用这样的代码:

Master mast = new Master 
{
    MasterId = new Guid(),
    Name = "test",
    Details = new List<Detail> 
    {
        new Detail { .DetailId = new Guid(), .Name = "Test1" },
        new Detail { .DetailId = new Guid(), .Name = "Test1" }
    }
};

using (transaction == Session.BeginTransaction) 
{
    Session.Save(mast);
    transaction.Commit();
}

这很有效,除了this post中概述的疯狂限制:NHibernate执行INSERT并将Detail.MasterId先置为NULL,然后执行UPDATE将其设置为真正的MasterId。

实际上,我不希望明细条目具有NULL MasterIds,因此如果我将MasterId字段设置为NOT NULL,则INSERT to Detail将失败,因为我说NHibernate试图输入MasterId = NULL。

我想我的问题归结为:

如何让上面的代码示例与现有的域模型一起使用(例如,不添加Detail.Master属性),并将数据库中的Detail.MasterId字段设置为NOT NULL?

有没有办法让Nhibernate在最初的INSERT中放入正确的MasterId,而不是之后运行UPDATE?这个设计决定有什么理由吗? - 我很难理解为什么会这样做。

3 个答案:

答案 0 :(得分:32)

NH3及以上版本允许在单向一对多映射的情况下更正保存实体,而不会烦恼save null - save - update周期,如果同时设置{{} 1}} on&lt; key&gt;和not-null="true" on&lt; one-to-many&gt;

FluentNHibernate代码片段:

inverse="false"

答案 1 :(得分:14)

你做不到。引用my answer关于您链接到的其他问题的链接:

  

非常重要注意:如果<key>关联的<one-to-many>列声明为NOT NULL,则NHibernate在创建或更新关联时可能会导致约束违规。要防止出现此问题,必须使用标记为inverse="true"的多值结束(集合或包)的双向关联。请参阅本章后面的双向关联讨论。

编辑:正如Hazzik正确指出的那样,NHibernate 3及以上版本已经发生了变化。可悲的是,文档还没有更新,所以这里是Hazzik:

  

[如果你]在inverse="false"上设置not-null<key>,NH3及以上版本只会执行两次insert-insert-update插入。

答案 2 :(得分:4)

NHibernate这样做的原因是因为:
当它保存细节时,它只知道细节知道的东西。因此忽略在后台发生的任何主引用。 只有在保存主文件时,它才会看到关系,并使用主文件的ID更新集合的元素。
这是从面向对象的角度来看的逻辑。然而,从保存的角度来看,逻辑上略显不足。我想你总是可以提交错误报告,或者查看它是否已经提交过,并要求他们进行更改。但我认为他们有其特定的(设计/域名)原因。

相关问题