我将nHibernate与Sybase一起使用,并且在保存到表中时出现 TooManyRowsAffectedException “ 意外行数:5;预期:1 ”,原因这是因为在数据库上触发了触发器。
不幸的是,我不允许更改触发器(即添加“ set NOCOUNT ON
”-像这里:NHibernate TooManyRowsAffectedException)
相反,我需要让nHibernate忽略行数。为此,我尝试了:TooManyRowsAffectedException with encrypted triggers,但没有任何运气:
当我调用NonBatchingBatcherWithoutVerification
时执行注入的已更改AddToBatch
.Commit()
,但仍会引发行计数异常。
在我编写自己的“ NonBatchingBatcherWithoutVerification”之前(见下文),在编写自己的注入类(没有引发行计数异常)之后,将其插入到CLIENT(第一个表)BUT中时遇到触发错误。 PERSON插入(第二插入而不是第一CLIENT插入)
我的代码如下:
设置nHibernate配置(注入了NonVerifyingBatcherFactory : IBatcherFactory
)并保存到数据库:
var cfg = new Configuration();
cfg.DataBaseIntegration(x =>
{
x.ConnectionString ="Data Source='';Database=;Port='';UID='';PWD=''";
x.Dialect<SybaseASE15Dialect>();
x.LogSqlInConsole = true;
x.BatchSize = 1;
x.Driver<DriverWithCustomBatcherFactory>(); });
cfg.DataBaseIntegration(db => db.Batcher<NonVerifyingBatcherFactory>());
cfg.Configure();
var sesFact = cfg.BuildSessionFactory();
using (var session = sesFact.OpenSession()) {
using (var tx = session.BeginTransaction()){
Person newPerson = new Person();
newPerson.Title = "Mr";
newPerson.Forenames = "THOMAS";
newPerson.Surname = "BYRNE";
newPerson.ClientType = "P";
newPerson.LanguageCode = "ENG";
newPerson.NationalityCode = "GBR";
newPerson.NormalCountryOfResidence = "GBR";
var nextClientId = session.QueryOver<Client>()
.Select(Projections.Max<Client>(c => c.ClientId))
.SingleOrDefault<int>() + 1;
session.Save(newPerson);
tx.Commit();
}
新注入的实现IBatcherFactory的NonVerifyingBatcherFactory类
public class NonVerifyingBatcherFactory : IBatcherFactory
{
public virtual IBatcher CreateBatcher(ConnectionManager connectionManager, IInterceptor interceptor)
{
return new NonBatchingBatcherWithoutVerification(connectionManager, interceptor);
}
}
我尝试实现AddToBatch
和DoExecuteBatch
-都没有 VerifyOutcomeNonBatched
public class NonBatchingBatcherWithoutVerification : NonBatchingBatcher
{
public NonBatchingBatcherWithoutVerification(ConnectionManager connectionManager, IInterceptor interceptor)
: base(connectionManager, interceptor)
{
//BatchSize = 1;
}
public override void AddToBatch(IExpectation expectation)
{
IDbCommand cmd = CurrentCommand;
ExecuteNonQuery(cmd);
// Removed the following line
//expectation.VerifyOutcomeNonBatched(rowCount, cmd);
}
protected override void DoExecuteBatch(System.Data.IDbCommand ps)
{
//IDbCommand cmd = CurrentCommand;
//ExecuteNonQuery(ps);
}
}
public class DriverWithCustomBatcherFactory : SybaseAseClientDriver, IEmbeddedBatcherFactoryProvider
{
public Type BatcherFactoryClass
{
get { return typeof(NonVerifyingBatcherFactory); }
}
}
或者没有正确配置分批-但是仅x.AdoNetBatchSize
仅x.BatchSize
:
cfg.DataBaseIntegration(
x =>
{
x.ConnectionString ="Data Source='';Database=;Port='';UID='';PWD=''";
x.Dialect<SybaseASE15Dialect>();
x.LogSqlInConsole = true;
在hibernate.cfg.xm lfile中添加了以下内容:
<property name="adonet.factory_class">NHibernateTest.NonVerifyingBatcherFactory, NHibernateTest</property>
<property name="adonet.batch_size">100</property>
CLIENT和PERSON映射设置如下:
<id name="ClientId" column="CLIENT_ID" type = "int">
<generator class="assigned"/>
</id>
<property name="LanguageCode" column="LANGUAGE_CODE" type = "string"/>
<property name="ClientType" column="CLIENT_TYPE" type = "string"/>
<joined-subclass name="Person" table="PERSON">
<key column="CLIENT_ID" />
<property name="Surname" column="SURNAME"/>
</joined-subclass>
<id name = "ID">
<generator class = "native"/>
</id>
<property name = "CLIENT_ID"/>
<property name = "SURNAME"/>
<property name = "FORENAMES"/>
重获 保存到PERSON表时,首先将CLIENT记录保存到CLINE表-(继承并保存在.hbm.xml文件中)
如果配置中不存在adonet.factory_class和adonet.batch_size ,我会得到: TooManyRowsAffectedException “ 意外行数:** 5; 预期:1 **” <<-我认为是来自CLIENT触发器
如果config中存在adonet.factory_class和adonet.batch_size ,我会得到: TooManyRowsAffectedException “ 意外的行数:** 32; 预期:1 **” <<-从我认为的PERSON触发器
任何帮助将不胜感激,谢谢!