每个
都必须有主键
1、 每个表都必须有主键
2、 自增字段(native)
3、one-to-many
出错原因
1、Could not excute query :HQL语句出错
2、in expected: bumen [select bumen from Bumen bumen]:未将配置文件属性改成“嵌入的资源”
3、could not resolve property:查询语句中,定义类对象后,具体字段区分大小写(应与类中变量名同)
4、The following types may not be used as proxies:类中定义变量未添加virtual
5、多表关联,主外键
6、可以将查询出来的字段属性组建成一个新的类,需要定义配置文件,在类文件中需添加
构造函数。
"select distinct new
ViewGwFile(gwFileDetail.Id,gwFileDetail.Gwdm,gwFileDetail.GwNameLb,gwFileDetail.GwFileLb,gwFileDetail.Seen,gwFileDetail.SignonNgr,gwFileDetail.Ngr,gwFileDetail.SignonR,gwFileDetail.Ddsj,gwFileDetail.Clqk,gwFileDetail.Zh,gwFileDetail.Nian,gwFileDetail.Hao,gwFileDetail.Mj,gwFileDetail.Jb,gwFileDetail.Qfqm,gwFileDetail.Qfrq,gwFileDetail.Bt,gwFileDetail.SignonS,gwFileDetail.State) from GwFileDetail as gwFileDetail inner join gwFileDetail.gwfileprocess as process
where 1=1";
使用NHibernate, Oracle Clob/NClob无法插入、乱码问
服务器Oracle 9i,客户端Oracle 10g。
问题1:
NHibernate配置的Driver为NHibernate.Driver.OracleClientDriver,存入Clob、NClob字段,
值比较大时报错,错误信息
中文:ORA-01461: 仅可以为插入 LONG 列的 LONG 值赋值
英文:ORA-01461: can bind a LONG value only for insert into a LONG column
Google一下有很多人碰到这个问题,有人猜测是MS System.Data.OracleClient的一个Bug,
方法是改用Oracle提供的Oracle.DataAccess。
解决方法:
下载安装ODAC (Oracle Data Access Components),将NHibernate的Driver配置为
NHibernate.Driver.OracleDataClientDriver,确保运行目录下有Oracle.DataAccess.dll文件。
问题2:
使用Oracle.DataAccess之后可以向一个NClob字段中插入长文本,但文本有的情况下会变成乱码。具体表现是输入一些中文
,保存后正常;输入英文字符,保存后正常;输入一段中英文混杂的html,保存后变成乱码。
排除了服务器、客户端Oracle字符集设置问题。跟踪NHibernate,在调用IDbCommand执行SQL语句时,参数中的值是正常的,因此排除了程序中对文本的编码、解码问题。
经过测试,使用下面的方式存入NClob的值不会变为乱码:
using Oracle.DataAccess.Client;
OracleConnection con = new OracleConnection("......"); con.Open();
OracleTransaction tran = con.BeginTransaction(); OracleCommand command = con.CreateCommand(); command.CommandType = CommandType.Text; command.CommandText = "update cms_template set temp_content=:p where temp_id=4";
OracleParameter param = command.CreateParameter();
param.ParameterName = ":p";
param.Value = this.textBox1.Text;
param.OracleDbType = OracleDbType.NClob; command.Parameters.Add(param);
command.ExecuteNonQuery();
tran.Commit();
con.Close();
最关键的一句是将param.OracleDbType设置为OracleDbType.NClob,这样Oracle.DataAccess就知道怎样正确处理这个参数了。
NHibernate为了兼容多数据库,统一使用IDbParameter接口,对于NHibernate内部来讲这个问题不好解决,我的方法是为CLob、NClob类型的属性实现一个
NHibernate.UserTypes.IUserType,在它的NullSafeSet方法中,修改IDbCommand中该字段
对应的IDbParameter的OracleDbType值,具体实现如下: public abstract class PatchForOracleLobField : IUserType
{
public PatchForOracleLobField()
{
}
public bool IsMutable
{
get { return true; }
}
public Type ReturnedType
{
get { return typeof(String); }
}
public SqlType[] SqlTypes
{
get { return new SqlType[] { new SqlType(DbType.String) }; }
}
public object DeepCopy(object value)
{
return value;
}
public new bool Equals(object x, object y)
{
return x == y;
}
public int GetHashCode(object x)
{
return x.GetHashCode();
}
public object Assemble(object cached, object owner)
{
return DeepCopy(cached);
}
public object Disassemble(object value)
{
return DeepCopy(value);
}
public object NullSafeGet(IDataReader rs, string[] names, object owner)
{
return NHibernate.NHibernateUtil.StringClob.NullSafeGet(rs, names[0]);
}
public abstract void NullSafeSet(IDbCommand cmd, object value, int index);
public object Replace(object original, object target, object owner)
{
return original;
}
}
public class OracleClobField : PatchForOracleLobField {
public override void NullSafeSet(IDbCommand cmd, object value, int index)
{
if (cmd is OracleCommand)
{
//CLob、NClob类型的字段,存入中文时参数的OracleDbType必须设置为OracleDbType.Clob
//否则会变成乱码(Oracle 10g client环境)
OracleParameter param = cmd.Parameters[index] as OracleParameter;
if (param != null)
{
param.OracleDbType = OracleDbType.Clob;
param.IsNullable = true;
}
}
NHibernate.NHibernateUtil.StringClob.NullSafeSet(cmd, value, index);
}
}
public class OracleNClobField : PatchForOracleLobField {
public override void NullSafeSet(IDbCommand cmd, object value, int index)
{
if (cmd is OracleCommand)
{
//CLob、NClob类型的字段,存入中文时参数的OracleDbType必须设置为OracleDbType.Clob
//否则会变成乱码(Oracle 10g client环境)
OracleParameter param = cmd.Parameters[index] as OracleParameter;
if (param != null)
{
param.OracleDbType = OracleDbType.NClob;
param.IsNullable = true;
}
}
NHibernate.NHibernateUtil.StringClob.NullSafeSet(cmd, value, index);
}
}