public
Last active

Oracle XML Type Test

  • Download Gist
CustomOracleDataClientDriver.cs
C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
using System;
using System.Data;
using System.Reflection;
using NHibernate;
using NHibernate.AdoNet;
using NHibernate.Driver;
using NHibernate.Engine.Query;
using NHibernate.SqlTypes;
using NHibernate.Util;
using Oracle.DataAccess.Client;
 
namespace OracleXmlTypeTest {
/// <summary>
/// A NHibernate Driver for using the Oracle.DataAccess DataProvider
/// </summary>
/// <remarks>
/// Code was contributed by <a href="http://sourceforge.net/users/jemcalgary/">James Mills</a> on the NHibernate forums in this <a
/// href="http://sourceforge.net/forum/message.php?msg_id=2952662">post</a> .
/// </remarks>
public class CustomOracleDataClientDriver : ReflectionBasedDriver, IEmbeddedBatcherFactoryProvider {
private const string DriverAssemblyName = "Oracle.DataAccess";
private const string ConnectionTypeName = "Oracle.DataAccess.Client.OracleConnection";
private const string CommandTypeName = "Oracle.DataAccess.Client.OracleCommand";
private static readonly SqlType GuidSqlType = new SqlType(DbType.Binary, 16);
private readonly PropertyInfo oracleDbType;
private readonly object oracleDbTypeRefCursor;
private readonly object oracleDbTypeXmlType;
 
/// <summary>
/// Initializes a new instance of <see cref="OracleDataClientDriver" /> .
/// </summary>
/// <exception cref="HibernateException">Thrown when the
/// <c>Oracle.DataAccess</c>
/// assembly can not be loaded.</exception>
public CustomOracleDataClientDriver()
: base(
DriverAssemblyName,
ConnectionTypeName,
CommandTypeName) {
var parameterType = ReflectHelper.TypeFromAssembly("Oracle.DataAccess.Client.OracleParameter",
DriverAssemblyName, false);
this.oracleDbType = parameterType.GetProperty("OracleDbType");
 
var oracleDbTypeEnum = ReflectHelper.TypeFromAssembly("Oracle.DataAccess.Client.OracleDbType",
DriverAssemblyName, false);
this.oracleDbTypeRefCursor = Enum.Parse(oracleDbTypeEnum, "RefCursor");
this.oracleDbTypeXmlType = Enum.Parse(oracleDbTypeEnum, "XmlType");
}
 
/// <summary>
/// </summary>
public override bool UseNamedPrefixInSql {
get { return true; }
}
 
/// <summary>
/// </summary>
public override bool UseNamedPrefixInParameter {
get { return true; }
}
 
/// <summary>
/// </summary>
public override string NamedPrefix {
get { return ":"; }
}
 
#region IEmbeddedBatcherFactoryProvider Members
 
Type IEmbeddedBatcherFactoryProvider.BatcherFactoryClass {
get { return typeof (OracleDataClientBatchingBatcherFactory); }
}
 
#endregion
 
/// <remarks>
/// This adds logic to ensure that a DbType.Boolean parameter is not created since ODP.NET doesn't support it.
/// </remarks>
protected override void InitializeParameter(IDbDataParameter dbParam, string name, SqlType sqlType) {
// if the parameter coming in contains a boolean then we need to convert it
// to another type since ODP.NET doesn't support DbType.Boolean
switch (sqlType.DbType) {
case DbType.Boolean:
base.InitializeParameter(dbParam, name, SqlTypeFactory.Int16);
break;
case DbType.Guid:
base.InitializeParameter(dbParam, name, GuidSqlType);
break;
case DbType.Xml:
dbParam.ParameterName = this.FormatNameForParameter(name);
this.oracleDbType.SetValue(dbParam, this.oracleDbTypeXmlType, null);
break;
default:
base.InitializeParameter(dbParam, name, sqlType);
break;
}
}
 
protected override void OnBeforePrepare(IDbCommand command) {
base.OnBeforePrepare(command);
 
((OracleCommand) command).BindByName = true;
 
var detail = CallableParser.Parse(command.CommandText);
 
if (!detail.IsCallable)
return;
 
command.CommandType = CommandType.StoredProcedure;
command.CommandText = detail.FunctionName;
 
var outCursor = command.CreateParameter();
this.oracleDbType.SetValue(outCursor, this.oracleDbTypeRefCursor, null);
 
outCursor.Direction = detail.HasReturn ? ParameterDirection.ReturnValue : ParameterDirection.Output;
 
command.Parameters.Insert(0, outCursor);
}
}
}
EntityWithXml.hbm.xml
XML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
<?xml version="1.0"?>
 
<hibernate-mapping
xmlns="urn:nhibernate-mapping-2.2"
assembly="OracleXmlTypeTest"
namespace="OracleXmlTypeTest">
 
<class name="EntityWithXml" table="XML_TEST">
<id name="Id">
<generator class="assigned" />
</id>
<property name="XmlProperty">
<column name="XML_COLUMN" sql-type="xmltype" />
</property>
</class>
</hibernate-mapping>
Hibernate.cfg.xml
XML
1 2 3 4 5 6 7 8 9 10 11 12 13
<?xml version="1.0" encoding="utf-8"?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" >
<session-factory name="NHibernate.Test">
<property name="connection.driver_class">OracleXmlTypeTest.CustomOracleDataClientDriver, OracleXmlTypeTest</property>
<property name="connection.connection_string">
...
</property>
<property name="show_sql">false</property>
<property name="hbm2ddl.auto">create</property>
<property name="dialect">NHibernate.Dialect.Oracle10gDialect</property>
<property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
</session-factory>
</hibernate-configuration>
OracleXmlTypeTest.cs
C#
1 2 3 4 5 6 7 8
using System.Xml.Linq;
 
namespace OracleXmlTypeTest {
public class EntityWithXml {
public virtual int Id { get; set; }
public virtual XDocument XmlProperty { get; set; }
}
}
Program.cs
C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
using System;
using System.Xml.Linq;
using NHibernate.Cfg;
using NHibernate.Linq;
 
namespace OracleXmlTypeTest {
internal class Program {
private static void Main(string[] args) {
var config = new Configuration();
 
config.Configure();
config.AddAssembly(typeof (Program).Assembly);
 
var sf = config.BuildSessionFactory();
 
using (var session = sf.OpenSession()) {
session.SaveOrUpdate(new EntityWithXml {Id = 1, XmlProperty = new XDocument(new XElement("Test", "OK"))});
session.Flush();
}
 
using (var session = sf.OpenSession())
foreach (var entity in session.Query<EntityWithXml>())
Console.WriteLine(entity.XmlProperty);
}
}
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.