流畅的NHibernate - 使用复合键保存实体

时间:2009-07-27 18:31:29

标签: nhibernate fluent-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表)将连接表映射到实体并以这种方式使用它更简单。

1 个答案:

答案 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可以完成更少的工作,所以你必须收拾残局。