最近项目有一个问题困扰了我很久--中文问题,网上对ActiveRecord的文档解释的很少,对中文乱码的问题更少,自己尝试了很多方法都没有解决,由于ActiveRecord是对NHibernate 的包装,再加上之前做Java项目的时候Hibernate通过自己写一个类型函数解决中文的问题,那么ActiveRecord也一定可以,仿着之前写过的Java类自己又写了一个类型转换的函数,如下:
//===================================================================================
//
// 文件名(File Name): EncodeConversion.cs
//
// 功能描述(Description): 用于转码
//
// 数据表(Table):
//
// 作者(Author): CHENLUZHONG
//
// 日期(Create Date): 2016.01.13
//
// 修改日期(Revision Histrory):
// R1:
// 修改作者:
// 修改日期:
// 修改理由:
//
//
//
//===================================================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using log4net;
using System.Reflection;
namespace StaticData.Common
{
class EncodeConversion
{
//static ILog log = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
///
/// </summary>
/// <param name="str">源字符</param>
/// <param name="sourceCode">原编码</param>
/// <param name="resultCode">需要转成的编码</param>
/// <returns>转码后的字符</returns>
public static string Convert(string str,string sourceCode,string resultCode)
{
System.Text.Encoding sourece, result;
string resultStr = null ;
sourece = System.Text.Encoding.GetEncoding(sourceCode);
result = System.Text.Encoding.GetEncoding(resultCode);
byte[] iso;
try
{
iso = sourece.GetBytes(str);
resultStr = result.GetString(iso);
}
catch (Exception e)
{
throw e;
//log.Error("转码失败!",e);
}
return resultStr;
}
}
}
/*转类型的类*/
GBKString.class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate.UserTypes;
using System.Data;
using NHibernate.SqlTypes;
namespace StaticData.Common
{
public class GBKString : IUserType
{
private static SqlType[] TYPES = new SqlType[] { new SqlType(DbType.String)};
public GBKString():base()
{
}
public object Assemble(object cached, object owner)
{
return DeepCopy(cached);
}
public object DeepCopy(object value)
{
if (value == null)
return null;
return value.ToString();
}
public object Disassemble(object value)
{
return DeepCopy(value);
}
public int GetHashCode(object x)
{
return x.GetHashCode();
}
public bool IsMutable
{
get { return false; }
}
public bool Equals(object x, object y)
{
return (x == y) || (x != null && y != null && (x.Equals(y)));
}
public object NullSafeGet(System.Data.IDataReader rs, string[] names, object owner)
{
string value = (string)NHibernate.NHibernateUtil.String.NullSafeGet(rs,names[0]);
if (null == value)
{
return null;
}
else
{
try
{
value = EncodeConversion.Convert(value, "windows-1252", "gb2312"); //读取时把数据库的编码转成中文的
}
catch (Exception e)
{
throw e;
}
return value;
}
}
public void NullSafeSet(System.Data.IDbCommand cmd, object value, int index)
{
if (null == value)
{
NHibernate.NHibernateUtil.String.NullSafeSet(cmd, value, index);
}
else
{
string val = value.ToString();
try
{
val = EncodeConversion.Convert(val, "gb2312", "windows-1252"); //写入时把中文转成数据库里的编码
}
catch (Exception e)
{
throw e;
}
NHibernate.NHibernateUtil.String.NullSafeSet(cmd, val, index);
}
}
public object Replace(object original, object target, object owner)
{
return original;
}
public Type ReturnedType
{
get {return typeof(string); }
}
public NHibernate.SqlTypes.SqlType[] SqlTypes
{
get { return TYPES; }
}
}
}
/*model类,映射数据库的类*/
[ActiveRecord("model1")]
class model1:ActiveRecordBase
{
private string _NAMECN;//有中文名称的字段
[Property("NAMECN",ColumnType="StaticData.Common.GBKString,StaticData")]//ColumnType要指定要转类型的Class的路径,StaticData指的是该类所在的程序集,如果在本程序 那么就写本项目名称,如果是Dll指明Dll的名称即可
public string NAMECN
{
get{return this._NAMECN;}
set{this._NAMECN = value;}
}
}
经过测试转码后本地的客户端字符集无需配置跟数据的字符集一样,也能转换,大家可以把字符编码写到配置文件中,那么就可以随便转换了
以上是我这次项目的经验,希望对大家有帮助