NHibernate标识插入

时间:2013-04-21 13:18:09

标签: nhibernate

我一直在寻找并且用NHibernate找不到这个问题的好答案。

我正在使用一个使用NHibernate的API。我正在进行数据传输,我正在尝试使用他们的User对象来保存用户数据。

我创建了对象

User objUser = new User();

他们有一个映射文件,指定id设置为identity

<id name="Id" column="UserId" type="int">
  <generator class="native" />
</id>

但我的一个要求是将旧ID保存到用户表。我需要能够暂时将标识插​​入设置为ON并保存记录,但仍然可以使用User对象来保存关联的数据。

我尝试过这样的事情

 using (ISession session = MyDatabaseFactory.SessionFactory.OpenSession())
{
    using (ITransaction trans = session.BeginTransaction())
    {
       session.CreateSQLQuery("SET IDENTITY_INSERT Users  ON").UniqueResult();
       session.Save(objUser, objUser.Id);
       session.Flush();

       trans.Commit();

       session.CreateSQLQuery("SET IDENTITY_INSERT Users OFF").UniqueResult();

       session.Close();
       objUser= session1.Merge(objUser);
       }
 }

但是在尝试稍后再次保存用户对象时

objUser.Passwords.Add("password1");
                    objUser.Save()

我收到错误:具有相同标识符值的其他对象已与会话

关联

2 个答案:

答案 0 :(得分:0)

Save()尝试将新对象插入数据库。 您应该尝试Update(),它会更新数据库中现有记录的持久对象。 您还可以使用SaveOrUpdate()决定使用上述哪一项。

再次调用Save(),我认为它正在尝试插入具有相同Id的另一条记录。 The answer here有更多详情。

答案 1 :(得分:0)

如果您的要求仅适用于非常特殊的情况,例如:数据库更新或迁移,您可以使用不同的会话工厂,其中ID是assigend:

<id name="Id" column="UserId" type="int">
  <generator class="assigned" />
</id>

并指定id:

User objUser = new User() { UserId = 42 };

如果您的案例与正常的商业案例紧密结合,这不是一个很好的解决方案。

您可以尝试实施自己的IIdentifierGenerator。不要指望它简单直接。您可能有机会派生IdentityGenerator,合并Assigned生成器中的一些代码并将此SET IDENTITY_INSERT Users ON内容放入其中...生成器需要知道何时使用哪种策略。例如。当id仍为0时,让SQL Server创建一个,当它是其他东西时,插入指定的值。