2009-07-27 26 views
9

首先,我有如下表:功能NHibernate - 保存实体与复合键

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表),将连接表映射到一个实体并且以这种方式使用它是非常简单的。

回答

6

编辑(在上面放)

引自NHibernate的文档:

由于其固有的性质,使用这种发电机的实体不能被通过的ISession的saveOrUpdate()方法的方法保存。相反,如果通过调用ISession的Save()或Update()方法来保存或更新对象,则必须明确指定NHibernate。

http://www.nhforge.org/doc/nh/en/index.html#mapping-declaration-id-assigned(5.1.4.7)

复合ID具有发电机=分配。

这又回到了复合ID =吸吮:)


您还没有发出冲洗或提交。您可能习惯使用类似身份的东西,在保存时发出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可以做更少的工作,所以你必须捡起松懈。

+0

感谢您的快速回答。为了简洁起见,我把它放在了外面,但我把所有的呼叫放在一个与第二个例子非常相似的代码中。我也试过冲洗没有运气。 – jckeyes 2009-07-27 19:19:08