流畅的 NHibernate 将 XDocument 属性映射到 Oracle XMLType
我正在寻找从 XDocument 属性类型映射到 Oracle XMLType 的最佳方法?我正在映射到旧数据库并且无法控制架构。它是Oracle 9i。
我读到 nHibernate 版本 3 为这种类型的映射提供了开箱即用的功能。我正在使用具有流畅映射的版本 3.1,并且在创建时使用默认映射时收到以下错误:
System.ArgumentOutOfRangeException:指定的参数超出了有效值的范围。 在Oracle.DataAccess.Client.OracleParameter.set_DbType(DbType值) 在 d:\CSharp\NH\NH\nhibernate\src\NHibernate\Driver\DriverBase.cs 中的 NHibernate.Driver.DriverBase.SetCommandParameters(IDbCommand cmd, SqlType[] sqlTypes) 处:第 180 行 在 d:\CSharp\NH\NH\nhibernate\src\NHibernate\Driver\DriverBase.cs 中的 NHibernate.Driver.DriverBase.GenerateCommand(CommandType type, SqlString sqlString, SqlType[]parameterTypes) 处:第 136 行 在 d:\CSharp\NH\NH\nhibernate\src\NHibernate\AdoNet\AbstractBatcher.cs 中的 NHibernate.AdoNet.AbstractBatcher.Generate(CommandType type, SqlString sqlString, SqlType[]parameterTypes):第 78 行 在 d:\CSharp\NH\NH\nhibernate\src\NHibernate\AdoNet\AbstractBatcher.cs 中的 NHibernate.AdoNet.AbstractBatcher.PrepareBatchCommand(CommandType type, SqlString sql, SqlType[]parameterTypes) 处:第 146 行 在NHibernate.Persister.Entity.AbstractEntityPersister.Insert(对象id,对象[]字段,布尔[] notNull,Int32 j,SqlCommandInfo sql,对象obj,ISessionImplementor会话)在d:\ CSharp \ NH \ NH \ nhibernate \ src \ NHibernate\Persister\Entity\AbstractEntityPersister.cs:行2616 在 d:\CSharp\NH\NH\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs 中的 NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object id, Object[] fields, Object obj, ISessionImplementor session) 处:行3050 在 d:\CSharp\NH\NH\nhibernate\src\NHibernate\Action\EntityInsertAction.cs 中的 NHibernate.Action.EntityInsertAction.Execute() 处:第 59 行 在 d:\CSharp\NH\NH\nhibernate\src\NHibernate\Engine\ActionQueue.cs 中的 NHibernate.Engine.ActionQueue.Execute(IExecutable 可执行文件):第 136 行 在 d:\CSharp\NH\NH\nhibernate\src\NHibernate\Engine\ActionQueue.cs 中的 NHibernate.Engine.ActionQueue.ExecuteActions(IList list) 处:第 125 行 在 d:\CSharp\NH\NH\nhibernate\src\NHibernate\Engine\ActionQueue.cs 中的 NHibernate.Engine.ActionQueue.ExecuteActions() 处:第 170 行 在 d:\CSharp\NH\NH\nhibernate\src\NHibernate\Event\Default\AbstractFlushingEventListener.cs 中的 NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session) 处:第 241 行 在 d:\CSharp\NH\NH\nhibernate\src\NHibernate\Event\Default\DefaultFlushEventListener.cs 中的 NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event) 处:第 20 行 在 d:\CSharp\NH\NH\nhibernate\src\NHibernate\Impl\SessionImpl.cs 中的 NHibernate.Impl.SessionImpl.Flush() 处:第 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 列
I am looking for the best way to map from an XDocument property type to an Oracle XMLType? I am mapping to a legacy database and have no control over the schema. It is Oracle 9i.
I have read that version 3 of nHibernate provides out the box functionality for this type of mapping. I am using version 3.1 with fluent mappings and I receive the following error when using the default map on a create:
System.ArgumentOutOfRangeException : Specified argument was out of the range of valid values.
at Oracle.DataAccess.Client.OracleParameter.set_DbType(DbType value)
at NHibernate.Driver.DriverBase.SetCommandParameters(IDbCommand cmd, SqlType[] sqlTypes) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Driver\DriverBase.cs: line 180
at NHibernate.Driver.DriverBase.GenerateCommand(CommandType type, SqlString sqlString, SqlType[] parameterTypes) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Driver\DriverBase.cs: line 136
at NHibernate.AdoNet.AbstractBatcher.Generate(CommandType type, SqlString sqlString, SqlType[] parameterTypes) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\AdoNet\AbstractBatcher.cs: line 78
at NHibernate.AdoNet.AbstractBatcher.PrepareBatchCommand(CommandType type, SqlString sql, SqlType[] parameterTypes) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\AdoNet\AbstractBatcher.cs: line 146
at NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object id, Object[] fields, Boolean[] notNull, Int32 j, SqlCommandInfo sql, Object obj, ISessionImplementor session) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs: line 2616
at NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object id, Object[] fields, Object obj, ISessionImplementor session) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs: line 3050
at NHibernate.Action.EntityInsertAction.Execute() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Action\EntityInsertAction.cs: line 59
at NHibernate.Engine.ActionQueue.Execute(IExecutable executable) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Engine\ActionQueue.cs: line 136
at NHibernate.Engine.ActionQueue.ExecuteActions(IList list) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Engine\ActionQueue.cs: line 125
at NHibernate.Engine.ActionQueue.ExecuteActions() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Engine\ActionQueue.cs: line 170
at NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Event\Default\AbstractFlushingEventListener.cs: line 241
at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Event\Default\DefaultFlushEventListener.cs: line 20
at NHibernate.Impl.SessionImpl.Flush() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Impl\SessionImpl.cs: line 1470
I got round this my writing my own user type which converts between an XDocument and a string:
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();
}
}
This worked fine until the string was greater than 4000 characters in length. Now I get the error:
NHibernate.Exceptions.GenericADOException : could not insert: [XmlBlob#95586][SQL: INSERT INTO XMLBLOB (CAT_CODE, BLB_BLOB, BLB_ID) VALUES (?, ?, ?)]
----> Oracle.DataAccess.Client.OracleException : ORA-01461: can bind a LONG value only for insert into a LONG column
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
为了能够将 4000 多个字符保存到 XMLType 列,我需要进行的唯一更新是在用户类型实现的 set 方法中将参数类型设置为 OracleDbType.XmlType:
The only update I needed to be able to save more than 4000 characters to the XMLType column was to set the parameter type as OracleDbType.XmlType in the set method for my user type implementation: