我有一个非常简单的单向映射。 见下文:
public ContactMap()
{
Id(x => x.Id).GeneratedBy.Assigned();
Map(x => x.Name);
References(x => x.Device);
HasMany(x => x.Numbers)
.Not.Inverse()
.Not.KeyNullable()
.Cascade.AllDeleteOrphan()
.Not.LazyLoad()
.Fetch.Subselect();
Table("Contacts");
}
public PhoneNumberMap()
{
Id(x => x.Id).GeneratedBy.Native();
Map(x => x.Number);
Table("ContactNumbers");
}
根据这一职位 NHibernate的3及以上后,设定键为非null应该可以解决插入更新的问题(这个问题时,NHibernate的问题与外键设置为空,然后更新的插入,更新外键修正值) ,但是这不是我的情况。 当我设定键不可为空,NHibernate的问题有正确插入语句
INSERT INTO ContactNumbers
(Number,
ContactId)
VALUES ('(212) 121-212' /* @p0 */,
10 /* @p1 */);
正如你所看到的,它插入的ContactID场,但在那之后,它仍然发出更新语句
UPDATE ContactNumbers
SET ContactId = 10 /* @p0 */
WHERE Id = 34 /* @p1 */
因此,要澄清这个问题。 NHibernate的插入联系一行正确分配外键,之后,它会发出一个更新语句来更新外键(使用ContactID),这是多余的。
我怎样才能摆脱这种多余的更新语句? 谢谢。
顺便说一句,我使用的是最新版本的NHibernate和流利的NHibernate的。 该数据库是SQLite的
你必须设置"updatable"=false
你的键,以防止更新。
public ContactMap()
{
Id(x => x.Id).GeneratedBy.Assigned();
Map(x => x.Name);
References(x => x.Device);
HasMany(x => x.Numbers)
.Not.Inverse()
.Not.KeyNullable()
.Not.KeyUpdate() // HERE IT IS
.Cascade.AllDeleteOrphan()
.Not.LazyLoad()
.Fetch.Subselect();
Table("Contacts");
}
你不能为3.2.0测试版的。
在V3.2.0 Beta测试阶段的改良效果一到多介绍了这个反常现象单向一个一对多的关系(其实我不知道,如果是anormaly你把这个叫做什么)。
3.2之前,你需要设置外键,以便为这种关系的零点工作。 所以,我会忽略,出现这种情况的事实,只是去用它。 否则,你就需要把它变成一个完全双向的关系。
发行说明或JIRA问题
编辑同样的答案你点到后是修复save null-save-update
,而不是固定的addtional更新
尝试设置inverse
到true
的映射和分配代码的关系。
Inverse
意味着孩子是负责保存父的ID。
如
var contact = new Contact();
var phoneNumber = new PhoneNumber();
phoneNumber.Contact = contact;
这样,当您为******中国唱片做插入,NH可以插入的ContactID,而无需单独做更新。
这就是我以前在NH 2做,我将承担行为仍然工作在3相同。
我不知道,如果真能摆脱它。
尝试使用另一个ID生成原生。 它迫使NH只插入记录,以获得ID。 该ID用于会话中的每一个实体,所以它不能做以后插入。 它可以区分后续更新。 使用HI-LO或类似的东西。
编辑
你为什么不使用在这种情况下,一个组成部分? 你并不需要单独绘制的电话号码,如果他们只包含一个数字。 像这样的东西(我不是一个FNH用户,所以它可能是错的):
public ContactMap()
{
Id(x => x.Id).GeneratedBy.Assigned();
Map(x => x.Name);
References(x => x.Device);
HasMany(x => x.Numbers)
.Not.Inverse()
.Not.KeyNullable()
.Cascade.AllDeleteOrphan()
.Not.LazyLoad()
.Fetch.Subselect()
.Component(c =>
{
Map(x => x.Number);
})
.Table("ContactNumbers");
Table("Contacts");
}
这是什么特雷弗Pilley说。 使用inverse="true"
。 如果您选择不inverse="true"
,这是选择的结果。 你不能两者兼得。