首先,我有下表:
CREATE TABLE CustomerHub (
CustomerId INT NOT NULL,
HubId INT NOT NULL
)
我已映射到此实体:
public class CustomerHub
{
public int CustomerId {get;set;}
public int HubId {get;set}
//GetHashCode, Equals, Etc...
}
使用此映射:
public class CustomerHubMap : ClassMap<CustomerHub>
{
UseCompositeId()
.WithKeyProperty(x => x.CustomerId)
.WithKeyProperty(x => x.HubId);
}
我遇到的问题是,当我创建一个CustomerHub类型的新实体并尝试保存它时,数据库中没有任何内容。我能够检索一切都很好,只是没有保存它们。例如:
//this will work
var x = session.CreateCriteria(typeof(CustomerHub));
//this will not
using (var trans = session.BeginTransaction())
{
var custHub = new CustomerHub {CustomerId = 293, HubId = 1193};
var y = session.SaveOrUpdate(custHub);
trans.Commit();
}
奇怪的是,没有抛出任何异常,它只是没有做任何事情。我启动了NH Profiler(优秀的工具!),看起来它没有向数据库发出任何类型的插入命令。
思想?
注意:我意识到这个表看起来很像一个连接表(因为它在技术上是),并且最好在另一个实体(例如Customer)上作为ManyToMany关系服务...但是由于一些非常棘手的数据设计(即没有Hub表)将连接表映射到实体并以这种方式使用它更简单。
答案 0 :(得分:6)
编辑(置于顶部)
引自NHibernate docs:
由于其固有特性,使用此生成器的实体无法通过ISession的SaveOrUpdate()方法保存。相反,如果要通过调用ISession的Save()或Update()方法来保存或更新对象,则必须明确指定NHibernate。
http://www.nhforge.org/doc/nh/en/index.html#mapping-declaration-id-assigned(5.1.4.7)
复合ID具有generator = assigned。
这可以追溯到复合id = sucking:)
您没有发出刷新或提交。您可能习惯使用类似于在保存时发出INSERT的标识,但复合由您的代码而不是数据库分配,因此您需要刷新/提交以进行插入。
var custHub = new CustomerHub {CustomerId = 293, HubId = 1193};
var y = session.SaveOrUpdate(custHub);
session.Flush();
或
using(var tx = session.BeginTransaction())
{
var custHub = new CustomerHub {CustomerId = 293, HubId = 1193};
var y = session.SaveOrUpdate(custHub);
tx.Commit();
}
另外,一个注意事项:使用复合键会让你讨厌你的生活。复合键很多东西都不起作用,并不是很明显。基本上NHibernate可以完成更少的工作,所以你必须收拾残局。