Я ищу лучший способ сопоставления типа свойства 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