CompositeId和Identity_Insert

时间:2013-08-20 10:11:59

标签: sql-server nhibernate

我的类映射如下:

public class FooMap : ClassMap<Foo> 
{
  public FooMap()
  { 
    Table("Foo");
    LazyLoad();
    CompositeId().KeyProperty(x => x.ID, 
                              kp => kp.ColumnName("Id")
                                      .Type(typeof(long)))
                 .KeyProperty(x => x.ValidFrom);
   }
}

在MSSQL端,Id是标识列,表的PK由IdValidFrom组成。

以下是我用来保存的代码:

ISession session = SessionService.GetSession();    
new SqlCommand("SET IDENTITY_INSERT Foo ON",
                session.Connection as SqlConnection)
                .ExecuteNonQuery();

try
{
    // performs various versioning checks,
    // then saves using transaction.
    // The session is the same as above
    GenericDataService.Save(myFoo);
}
finally
{
    new SqlCommand("SET IDENTITY_INSERT Foo OFF",
                    session.Connection as SqlConnection)
                    .ExecuteNonQuery();
}

虽然我将Identity_Insert设置为ON,但我收到以下异常(保留ID并设置新ValidFrom时):

Cannot insert explicit value for identity column in table 'Foo' when IDENTITY_INSERT is set to OFF.

这是执行的SQL:

INSERT INTO Foo (C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, Id, ValidFrom) 
    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

有人可以解释为什么我仍然会得到这个例外吗?

1 个答案:

答案 0 :(得分:0)

如果问题与建议的Nathan Fisher之类的单独事务有关,那么NHibernate的ITransaction.Enlist(IDbCommand)方法应该修复它。尝试这样的事情:

using (var trx = session.BeginTransaction())
{
    ExecuteInNHTransaction(session, "SET IDENTITY_INSERT Foo ON");
    session.Save(myFoo);
    ExecuteInNHTransaction(session, "SET IDENTITY_INSERT Foo OFF");
    trx.Commit();
}
private static void ExecuteInNHTransaction(ISession session, string commandText)
{
    var command = new SqlCommand(commandText,
        (SqlConnection) session.Connection);
    session.Transaction.Enlist(command);
    command.ExecuteNonQuery();
}