当前位置:编程学习 > C#/ASP.NET >>

Nhibernate在oracle批量插入失败,求解?

<property name="adonet.batch_size">100</property>

 

加了这句,发现在oracle不起作用。一样的代码,如果在sql08下运行能生效。

 

using (var session = SessionFactory.NHSessionFactory.OpenStatelessSession())
            {
                using (var tx = session.BeginTransaction())
                {
                    try
                    {
                        foreach (var entity in entities)
                        {
                            session.Insert(entity);
                        }
                        tx.Commit();
                    }
                    catch (Exception ex)
                    {

                    }
                }
            }

 

oracle运行后如下图:



 

SQL08执行后如下图:



 

明显看出oracle不支持批量插入那样。再深看了NH源代码发现oracle批量导入,有一个类,NHibernate.AdoNet.OracleDataClientBatchingBatcherFactory

 

打算引入该类:

<property name="adonet.factory_class">NHibernate.AdoNet.OracleDataClientBatchingBatcherFactory,NHibernate</property>

但插入时看到有批量导入的样子了,但事务提交tx.commit或session.flush().报了一个对象无法实例化的错误,然后把这个session通道关闭了。又再尝试引用NH源码入项目调试,但没有发现效果。

--------------------编程问答-------------------- 我批量更新到是没有问题。批量插入我现在试试。
话说,你拿NHProfiler或者控制台能检测到生成的sql吗? --------------------编程问答-------------------- 我本地测试通过,并没有使用OracleDataClientBatchingBatcherFactory,数据也是oracle,也使用了事务。批量更新成功。
建议session.insert改为session.save试试
代码如下
 /// <summary>
        /// 批量添加
        /// </summary>
        /// <param name="listEntity"></param>
        public virtual void BatchAdd(IList<TEntity> listEntity)
        {
            using (ISession session = NHibernateHelper.CreateSession())
            {
                using (var tx = session.BeginTransaction())
                {
                    foreach (TEntity entity in listEntity)
                    {
                        if (NHibernateHelper.Validate(entity))
                        {
                            if (entity == null)
                            {
                                throw new ArgumentNullException("Add objects cannot be empty!");
                            }
                            session.Save(entity);
                        }
                    }
                    tx.Commit();
                    //session.Flush();

                }
                LogHelper.AddOptLog(session, typeof(TEntity).Name, "insert", "BatchAdd");
            }
        }
--------------------编程问答--------------------
引用 2 楼 lixiaolian7 的回复:
我本地测试通过,并没有使用OracleDataClientBatchingBatcherFactory,数据也是oracle,也使用了事务。批量更新成功。
建议session.insert改为session.save试试
代码如下


C# code
?



12345678910111213141516171819202122232425262728

 /// <su……

哥位,能加你QQ么?我尝试过还是不行哦。
--------------------编程问答--------------------
Quote: 引用 2 楼 lixiaolian7 的回复:

你好,你的QQ多少,大家交流一下,你给了的代码,我一早已经尝试过了,是不行的。我用nhibernate profiler输出过。难道是我的config配置出问题么?共享一下你那个配置文件。


<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
    <session-factory>
      <property name="connection.provider">
        NHibernate.Connection.DriverConnectionProvider
      </property>
      <property name="dialect">
        NHibernate.Dialect.Oracle10gDialect
      </property>
      <property name="connection.driver_class">
        NHibernate.Driver.OracleClientDriver
      </property>
      <property name="connection.connection_string">
        Data Source=orcl;User ID=test;pwd=test;Min Pool Size=20;Max Pool Size=50;Pooling=true;
      </property>
      <property name="current_session_context_class">thread_static</property>
      <property name="adonet.batch_size">100</property>
      <property name="show_sql">false</property>
      <property name="generate_statistics">true</property>
    </session-factory>
  </hibernate-configuration>
--------------------编程问答-------------------- 我的qq发你的私信里边了 --------------------编程问答-------------------- oracle没什么问题,一直都用的。是不是oracle用户的权限设置为不可插入? --------------------编程问答--------------------
引用 6 楼 yeness 的回复:
oracle没什么问题,一直都用的。是不是oracle用户的权限设置为不可插入?


是批量插入阿哥们,普遍的插入一定可以的了。 --------------------编程问答-------------------- --------------------编程问答--------------------
楼主最后将问题解决了,这源于nh的一个BUG。
在NH源代码中的Nhibernate.Driver.OracleClientDriver构造中如图改造。
然后引入Oracle.DataAccess.Clien即可。
补充:.NET技术 ,  ASP.NET
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,