如何在 Nhibernate 中定义 CHAR (ORACLE) 列?
我开始使用 Nhibernate 和 Oracle 来完成一个项目。
数据库是 Oracle 9.2,我无法更改架构或任何内容。
我正在使用 NH3.0 和 Oracle.DataAccess.dll 版本 2.111.7.20。
到目前为止,我已经映射了几个表并完成了一些查询。一切都运转良好。 我现在遇到了一个问题,我不知道如何解决它。
设计数据库的公司认为将所有字母数字字段创建为 CHAR 而不是 VARCHAR 或 VARCHAR2 是一个好主意。
我已将所有这些列映射为字符串,并且我的类定义了字符串字段。 后来我尝试通过主键(在 Oracle 中定义为 CHAR(10))加载实体。 我尝试加载的密钥只有 7 个字符长
例如:“CI00252” 显然我的实体无法加载。 使用 NProf 分析查询,我可以看到我的查询很好,如果我尝试在 Oracle Sql-Developer 中执行它,我会得到结果集。 如果我像这样填充字符串“CI00252
”,我只能设法使其工作。
考虑到数据库上定义的大多数字段都是 CHAR,我不可能在执行查询之前填充所有内容。
我可以做什么来解决这个问题?
PS:我在这里看到其他一些人也有同样的问题,但我找不到任何合适的答案。
更新:
我正在阅读blog ,这个人对另一种数据类型也有类似的问题。我尝试调整代码
public SqlType[] SqlTypes
{
get
{
SqlType[] types = new SqlType[1];
types[0] = new SqlType(DbType.StringFixedLength);
return types;
}
}
**
,显然,一切正常,但是......我不知道为什么。
using System;
using System.Data;
using NHibernate;
using NHibernate.SqlTypes;
using NHibernate.UserTypes;
namespace ConsoleOracleNhibernate.OracleTypes
{
public class CharUserType : IUserType
{
public object NullSafeGet(IDataReader rs, string[] names, object owner)
{
string resultString = (string)NHibernateUtil.String.NullSafeGet(rs, names[0]);
if (resultString != null)
return resultString.Trim();
return null;
}
public void NullSafeSet(IDbCommand cmd, object value, int index)
{
if (value == null)
{
NHibernateUtil.String.NullSafeSet(cmd, null, index);
return;
}
value = ((String)value).Trim();
NHibernateUtil.String.NullSafeSet(cmd, value, index);
}
public object DeepCopy(object value)
{
if (value == null) return null;
return string.Copy((String)value);
}
public object Replace(object original, object target, object owner)
{
return original;
}
public object Assemble(object cached, object owner)
{
return DeepCopy(cached);
}
public object Disassemble(object value)
{
return DeepCopy(value);
}
public SqlType[] SqlTypes
{
get
{
SqlType[] types = new SqlType[1];
types[0] = new SqlType(DbType.StringFixedLength);
return types;
}
}
public Type ReturnedType
{
get { return typeof(String); }
}
public bool IsMutable
{
get { return false; }
}
public new bool Equals(object x, object y)
{
if (x == null || y == null) return false;
return x.Equals(y);
}
public int GetHashCode(object x)
{
return x.GetHashCode();
}
}
}
和我的地图:
<key-property name="CustomerCode" column="ANCOCO" type="ConsoleOracleNhibernate.OracleTypes.CharUserType, ConsoleOracleNhibernate" length="10"></key-property>
这里有人可以尝试帮助我了解正在发生的事情吗?
I am starting to work with Nhibernate and Oracle for a project.
The database is Oracle 9.2 and I can't change the schema or anything.
I am using NH3.0 and the Oracle.DataAccess.dll ver 2.111.7.20.
So far I've mapped a couple of table and have done some queries. Everything works pretty well.
I've bumped into a problem now and I don't know how to fix it.
The company who's designed the database thought it was a good idea to create all the alphanumeric fields as CHAR instead of VARCHAR or VARCHAR2.
I've mapped all these columns as String and my classes have String fields defined.
Later on I was trying to load an entity by its primary key, defined as CHAR(10) in Oracle.
The key I was trying to load is only 7 characters long
EG: 'CI00252'
Apparently my entity can't be loaded.
Profiling the query with NHProf I can see that my query is fine and if I try to execute it in Oracle Sql-Developer I get the resultset.
I can only manage to make it work if I pad my string like this 'CI00252
'.
Considering that most of the fields defined on the database are CHAR, it is impossible for me to pad everything before executing the query.
What can I do to fix this problem?
PS: I've seen some other people with the same problem here but I couldn't find any appropriate answer.
UPDATE:
I was reading a blog and this guy had a similar problem with another data-type.I've tried to adpapt the code
public SqlType[] SqlTypes
{
get
{
SqlType[] types = new SqlType[1];
types[0] = new SqlType(DbType.StringFixedLength);
return types;
}
}
**
and, apparently, everything is working but ... I don't know why.
using System;
using System.Data;
using NHibernate;
using NHibernate.SqlTypes;
using NHibernate.UserTypes;
namespace ConsoleOracleNhibernate.OracleTypes
{
public class CharUserType : IUserType
{
public object NullSafeGet(IDataReader rs, string[] names, object owner)
{
string resultString = (string)NHibernateUtil.String.NullSafeGet(rs, names[0]);
if (resultString != null)
return resultString.Trim();
return null;
}
public void NullSafeSet(IDbCommand cmd, object value, int index)
{
if (value == null)
{
NHibernateUtil.String.NullSafeSet(cmd, null, index);
return;
}
value = ((String)value).Trim();
NHibernateUtil.String.NullSafeSet(cmd, value, index);
}
public object DeepCopy(object value)
{
if (value == null) return null;
return string.Copy((String)value);
}
public object Replace(object original, object target, object owner)
{
return original;
}
public object Assemble(object cached, object owner)
{
return DeepCopy(cached);
}
public object Disassemble(object value)
{
return DeepCopy(value);
}
public SqlType[] SqlTypes
{
get
{
SqlType[] types = new SqlType[1];
types[0] = new SqlType(DbType.StringFixedLength);
return types;
}
}
public Type ReturnedType
{
get { return typeof(String); }
}
public bool IsMutable
{
get { return false; }
}
public new bool Equals(object x, object y)
{
if (x == null || y == null) return false;
return x.Equals(y);
}
public int GetHashCode(object x)
{
return x.GetHashCode();
}
}
}
and my mapping:
<key-property name="CustomerCode" column="ANCOCO" type="ConsoleOracleNhibernate.OracleTypes.CharUserType, ConsoleOracleNhibernate" length="10"></key-property>
Is there anyone here who can try to help me to understand what's happening?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我的答案在问题的更新中。
My answer is in the update of the question.