Search found 1 match

by rstacey481
Mon 23 Jan 2012 11:56
Forum: dotConnect for Oracle
Topic: NHibernate 3.2 GA and Parameter Name error
Replies: 13
Views: 6906

NHibernate Driver

I'm pretty sure that this problem is all down to two simple things...

1. The fact that the Devart.Oracle.OracleParameter removes the ':' prefix from the ParameterName property.
2. The fact that the DevartOracleDriver for NHibernate returns true for the UseNamedPrefixInParameter property.

When you combine these settings with NHibernate you end up with parameters being removed from the Commands ParameterCollection that shouldn't be removed. This behaviour is due to the DriverBase RemoveUnusedCommandParameters method being unable to correctly identify parameter names in the collection.

Using the modified driver below all these vanishing parameter problems, well... vanish and everything seems to behave as it should. I have run some tests on this driver but they are by no means exhaustive so if anyone out there would like to test to destruction and modify accordingly I'd be interested in the results.

Code: Select all

using System.Data;
using System.Reflection;
using NHibernate.AdoNet;
using NHibernate.SqlTypes;
using NHibernate.Util;

namespace NHibernate.Driver
{

    public class DevartOracleDriver : ReflectionBasedDriver, IEmbeddedBatcherFactoryProvider
    {
        private const string AssemblyName = "Devart.Data.Oracle";
        private const string ConnectionTypeName = "OracleConnection";
        private const string CommandTypeName = "OracleCommand";
        private static readonly SqlType GuidSqlType = new SqlType(DbType.Binary, 16);
        private readonly PropertyInfo _oracleDbType;
        private readonly object _oracleDbTypeRaw;

        /// 
        /// Initializes a new instance of .
        /// 
        /// 
        /// Thrown when the Devart.Data.Oracle assembly can not be loaded.
        /// 
        public DevartOracleDriver()
            : base(AssemblyName, QualifiedName(ConnectionTypeName), QualifiedName(CommandTypeName))
        {
            System.Type parameterType = ReflectHelper.TypeFromAssembly(QualifiedName("OracleParameter"), AssemblyName, false);
            _oracleDbType = parameterType.GetProperty("OracleDbType");

            System.Type oracleDbTypeEnum = ReflectHelper.TypeFromAssembly(QualifiedName("OracleDbType"), AssemblyName, false);
            _oracleDbTypeRaw = System.Enum.Parse(oracleDbTypeEnum, "Raw");
        }

        /// 
        public override bool UseNamedPrefixInSql
        {
            get { return true; }
        }

        /// 
        public override bool UseNamedPrefixInParameter
        {
            get { return false; }
        }

        /// 
        public override string NamedPrefix
        {
            get { return ":"; }
        }

        protected override void InitializeParameter(IDbDataParameter dbParam, string name, SqlType sqlType)
        {
            if (sqlType.DbType == DbType.Guid)
            {
                base.InitializeParameter(dbParam, name, GuidSqlType);
                _oracleDbType.SetValue(dbParam, _oracleDbTypeRaw, null);
            }
            else
                base.InitializeParameter(dbParam, name, sqlType);
        }

        private static string QualifiedName(string typeName)
        {
            return string.Format("{0}.{1}", AssemblyName, typeName);
        }


        #region IEmbeddedBatcherFactoryProvider Members

        System.Type IEmbeddedBatcherFactoryProvider.BatcherFactoryClass
        {
            get { return typeof(OracleDataClientBatchingBatcherFactory); }
        }

        #endregion
    }
}