gre*_*mac 18 nhibernate one-to-many fluent-nhibernate
我正在尝试建立如下关系.每个主项目都有一个或多个详细信息项:
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; }
}
Run Code Online (Sandbox Code Playgroud)
和映射:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
在主数据库表:
masterId uniqueidentifier NOT NULL
name nvarchar(max) NULL
Run Code Online (Sandbox Code Playgroud)
和细节是:
DetailId uniqueidentifier NOT NULL
name nvarchar(max) NULL
MasterId uniqueidentifier NULL
foreign key (masterId) references [Master]
Run Code Online (Sandbox Code Playgroud)
我真的不在乎有一个从Detail回到Master的链接 - 换句话说,自己的Detail对象对我的域层并不感兴趣.它们将始终通过其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();
}
Run Code Online (Sandbox Code Playgroud)
这很好用,除了这篇文章中概述的疯狂限制: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?这个设计决定有什么理由吗? - 我很难理解为什么会这样做.
haz*_*zik 32
NH3及以上允许正确的存储实体单向,没有恼人的一个一对多映射的情况下save null
- save
- update
周期,如果同时设置not-null="true"
对<key>和inverse="false"
对<一个一对多>
FluentNHibernate代码片段:
public class MasterMap : ClassMap<Master>
{
public MasterMap()
{
Id(x => x.MasterId);
Map(x => x.Name);
HasMany(x => x.Details)
.Not.Inverse() //these options are very
.Not.KeyNullable() //important and work only if set together
.Not.KeyUpdate() //to prevent double update
.Cascade.All();
}
}
Run Code Online (Sandbox Code Playgroud)
Jam*_*ory 14
非常重要注意:如果关联的
<key>
列<one-to-many>
声明为NOT NULL,则NHibernate在创建或更新关联时可能会导致约束违规.要防止出现此问题,必须使用标记为的多值结束(集合或包)的双向关联inverse="true"
.请参阅本章后面的双向关联讨论.
编辑:正如Hazzik正确指出的那样,NHibernate 3及以上版本已经发生了变化.遗憾的是,文档还没有更新,所以这里是Hazzik:
[如果你]设置
inverse="false"
和not-null
打开<key>
,NH3及以上将只执行insert-insert-update的两个插入插入.