1

我一直在四处寻找,找不到 NHibernate 的这个问题的好答案。

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

我创建对象

User objUser = new User();

他们有一个映射文件,指定将 ID 设置为身份

<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()

我收到一个错误:具有相同标识符值的不同对象已与会话关联

4

2 回答 2

0

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

通过再次调用Save(),我认为它正在尝试插入具有相同 ID 的另一条记录。 这里的答案有更多细节。

于 2013-04-22T08:54:05.637 回答
0

如果您的要求只是针对非常特殊的情况,例如数据库更新或迁移,您可能会使用不同的会话工厂,其中 ID 是分配的:

<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 创建一个,当它是别的东西时,插入分配的值。

于 2013-04-22T15:15:01.887 回答