Свободное свойство XDocument сопоставления NHibernate для Oracle XMLType - PullRequest
0 голосов
/ 25 января 2012

Я ищу лучший способ сопоставления типа свойства XDocument с OracleType типа XML? Я сопоставляю с устаревшей базой данных и не имею никакого контроля над схемой. Это Oracle 9i.

Я прочитал, что версия 3 nHibernate предоставляет функциональные возможности для этого типа отображения. Я использую версию 3.1 с текущими отображениями и получаю следующую ошибку при использовании карты по умолчанию при создании:

System.ArgumentOutOfRangeException: указанный аргумент находится вне диапазона допустимых значений. в Oracle.DataAccess.Client.OracleParameter.set_DbType (значение DbType) в NHibernate.Driver.DriverBase.SetCommandParameters (IDbCommand cmd, SqlType [] sqlTypes) в d: \ CSharp \ NH \ NH \ nhibernate \ src \ NHibernate \ Driver \ DriverBase.cs: строка 180 в NHibernate.Driver.DriverBase.GenerateCommand (тип CommandType, SqlString sqlString, SqlType [] параметрTypes) в d: \ CSharp \ NH \ NH \ nhibernate \ src \ NHibernate \ Driver \ DriverBase.cs: строка 136 в NHibernate.AdoNet.AbstractBatcher.Generate (тип CommandType, SqlString sqlString, SqlType [] параметрTypes) в d: \ CSharp \ NH \ NH \ nhibernate \ src \ NHibernate \ AdoNet \ AbstractBatcher.cs: строка 78 в NHibernate.AdoNet.AbstractBatcher.PrepareBatchCommand (тип CommandType, SqlString sql, SqlType [] параметрTypes) в d: \ CSharp \ NH \ NH \ nhibernate \ src \ NHibernate \ AdoNet \ AbstractBatcher.cs: строка 146 в NHibernate.Persister.Entity.AbstractEntityPersister.Insert (идентификатор объекта, поля объекта [], логическое [] notNull, Int32 j, SqlCommandInfo sql, объект obj, сеанс ISessionImplementor) в каталоге d: \ CSharp \ NH \ NH \ nhibernate \ src \ NHibernate \ Persister \ Entity \ AbstractEntityPersister.cs: строка 2616 в NHibernate.Persister.Entity.AbstractEntityPersister.Insert (идентификатор объекта, поля объекта [], объект obj, сеанс ISessionImplementor) в каталоге d: \ CSharp \ NH \ NH \ nhibernate \ src \ NHibernate \ Persister \ Entity \ AbstractEntityPersister.cs: строка 3050 в NHibernate.Action.EntityInsertAction.Execute () в d: \ CSharp \ NH \ NH \ nhibernate \ src \ NHibernate \ Action \ EntityInsertAction.cs: строка 59 в NHibernate.Engine.ActionQueue.Execute (исполняемый файл IExecutable) в d: \ CSharp \ NH \ NH \ nhibernate \ src \ NHibernate \ Engine \ ActionQueue.cs: строка 136 в NHibernate.Engine.ActionQueue.ExecuteActions (список IList) в d: \ CSharp \ NH \ NH \ nhibernate \ src \ NHibernate \ Engine \ ActionQueue.cs: строка 125 в NHibernate.Engine.ActionQueue.ExecuteActions () в d: \ CSharp \ NH \ NH \ nhibernate \ src \ NHibernate \ Engine \ ActionQueue.cs: строка 170 в NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions (сеанс IEventSource) в d: \ CSharp \ NH \ NH \ nhibernate \ src \ NHibernate \ Event \ Default \ AbstractFlushingEventListener.cs: строка 241 в NHibernate.Event.Default.DefaultFlushEventListener.OnFlush (событие FlushEvent) в d: \ CSharp \ NH \ NH \ nhibernate \ src \ NHibernate \ Event \ Default \ DefaultFlushEventListener.cs: строка 20 в NHibernate.Impl.SessionImpl.Flush () в d: \ CSharp \ NH \ NH \ nhibernate \ src \ NHibernate \ Impl \ SessionImpl.cs: строка 1470

Я обошёл это, написав свой собственный тип пользователя, который преобразует XDocument в строку:

public SqlType[] SqlTypes
{
get { return (new SqlType[] { new StringClobSqlType() }); }
}

public Type ReturnedType
{
get { return (typeof(XDocument)); }
}

public object NullSafeGet(IDataReader rs, string[] names, object owner)
{
XDocument xDoc = null;

int columnIndex = rs.GetOrdinal(names[0]);
if (!rs.IsDBNull(columnIndex))
{
xDoc = XDocument.Parse((rs[columnIndex].ToString()));
}

return (xDoc);
}

public void NullSafeSet(IDbCommand cmd, object value, int index)
{
IDbDataParameter parameter = (IDbDataParameter)cmd.Parameters[index];

if (value == null)
{
parameter.Value = DBNull.Value;
}
else
{
XDocument xDoc = (XDocument)value;
parameter.Value = xDoc.ConvertToString();

}
}

Это работало нормально, пока длина строки не превысила 4000 символов. Теперь я получаю ошибку:

NHibernate.Exceptions.GenericADOException: не удалось вставить: [XmlBlob # 95586] [SQL: INSERT INTO XMLBLOB (CAT_CODE, BLB_BLOB, BLB_ID) VALUES (?,?,?)] ----> Oracle.DataAccess.Client.OracleException: ORA-01461: может связывать значение LONG только для вставки в столбец LONG

1 Ответ

0 голосов
/ 25 января 2012

Единственное обновление, которое мне нужно было, чтобы иметь возможность сохранить более 4000 символов в столбце XMLType, - это установить тип параметра как OracleDbType.XmlType в методе set для моей реализации пользовательского типа:

    public void NullSafeSet(IDbCommand cmd, object value, int index)
    {
        IDbDataParameter parameter = (IDbDataParameter)cmd.Parameters[index];
       ((OracleParameter)parameter).OracleDbTypeEx = OracleDbType.XmlType;

        if (value == null)
        {
            parameter.Value = DBNull.Value;
        }
        else
        {
            XDocument xDoc = (XDocument)value;
            parameter.Value = xDoc.ConvertToString();
        }
    }
...