调用方式:
mono在调用方式上与.net Framework完全相同,都是采用System.Data.OracleClient命名空间中的类来完成数据库操作。
需要注意的是,目前微软已经不建议在.net 平台上用System.Data.OracleClient了,因为Oracle自己提供了一个Oracle.Data.Access类库来提供.net对Oracle数据库的访问。然而在mono平台上,System.Data.OracleClient仍是最好的访问Oracle数据库的方式。
实现原理:
System.Data.OracleClient中的类库的实现靠的是通过P/Invoke调用libclntsh.so共享库的函数完成。
步骤:
(1)下载安装对应 的oracle client。
oracle-instantclient12.1-basic-12.1.0.1.0-1.i386.rpm instantclient-basic-linux-12.1.0.1.0.zip
我用的是CentOS,安装的rpm包,安装完后,类库会放到 /usr/lib/oracle/版本号/client/lib/ ,需要做一个软连接,否则Mono找不到需要的共享库
(2) 设置ldconfig ,使Mono能找到需要的共享库
sudo ln -s /usr/lib/oracle/12.1/client/lib/libclntsh.so.12.1 /usr/lib/oracle/12.1/client/lib/libclntsh.so
更新ldconfig设置:
在 /etc/ld.so.conf.d目录下新建 oracle-client.conf , 输入Oracle Client 类库的路径, /usr/lib/oracle/12.1/client/lib
别忘了执行 sudo ldconfig
(3)使用mono 写数据库访问代码,这个就不用我说了,跟标准的ADO.NET一样,我这里使用的是PetaPoco 微型ORM,具体请搜谷歌,度娘。
过程中遇到的错误:
(1)ORA-21561 OID generation failed.
解决办法:修改/etc/hosts 找到127.0.0.1 loopback localhost 在后面添加Linux机器的主机名( 使用hostname命令查看)
添加完后,如下面所示,其中VM-CentOS为我的主机名
127.0.0.1 lookback localhost VM-CentOS
(2) PetaPoco报空对象引用 的错误,修改PetaPoco.cs中下面代码:
public override void PreExecute(IDbCommand cmd)
{
//注掉下面一行,修改为下面的代码。Command对象里不存在"BindByName"的属性,此处会报错
//cmd.GetType().GetProperty("BindByName").SetValue(cmd, true, null);
PropertyInfo bindByNameInfo = cmd.GetType ().GetProperty ("BindByName");
if (bindByNameInfo!=null) {
bindByNameInfo.SetValue (cmd, true, null);
}
}
(3) 最后一个问题,
读取到的中文为乱码的问题,经查找是Linux下的client语言设置跟Oracle服务器语言字符集设置不一致造成的。
在服务器上执行:select userenv('language') from dual; 获取服务器的字符集
在Linux上设置客户端字符集:
一、sudo gvim /etc/bashrc
二、在文件最后添加 export NLS_LANG="Simplified Chinese_china".ZHS16GBK 注:此处的字符集要跟服务器字符集一致。
完成以后,注销当前用户,重新登录。
在Mono下使用PetaPoco + Oracle数据库进行开发过程中,暂遇到这些问题,特记录下来。希望对遇到同样问题的人有帮助 。