又是很久没写随笔了。。。趁今天起得早,记录一下前几天测试项目.net后台从SQL转成Oracle的心得吧
一、引用DLL
现在只要引用一个Oracle.ManagedDataAccess.dll就可以了,不用找一大堆DLL。另外,好像要装ODP.NET之类的,也弄不清具体要装什么,当时在家里机器上调试,报错后上网搜了一下,装了一大堆,最后就可以了。
后来去公司也试了,好像就是这个,去官网下载最新,按教程装下就可以,不知以后部署到服务器上要不要装这些。
二、Web.Config
<add name="XXX" providerName="Oracle.ManagedDataAccess.Client" connectionString="Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.0.XXX)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=ORCL)));User ID=XXX;Password=XXX;" />
三、Ado.NET读取数据
providerName="Oracle.ManagedDataAccess.Client"
Web.Config的这个providerName坑了我半天,原先公司同事有一个旧项目,providerName是写错的,但用Ado.NET读数据是可以读,用EF或DataReader要报没提供.NET Provider之类的错
providerName="Oracle.ManagedDataAccess"
OracleConnection conn = new OracleConnection { ConnectionString = System.Web.Configuration.WebConfigurationManager.ConnectionStrings["XXX"].ToString() }; conn.Open(); OracleCommand cmd = conn.CreateCommand(); cmd.CommandText = "select XX from XXX where rownum = 1"; OracleDataReader reader = cmd.ExecuteReader(); string xxStr = "未读取"; while (reader.Read()) { xxStr = reader["XX"].ToString(); }
四、封装好的SQL后台
string xxName = XXFactory.SqlRepositoryService.xxQuery.ExecuteScalar(@"select xxName from xxx where rownum=1");
公司有封装一套SqlHelper之类的公共方法,批量替换原先的SqlHelper为OracleHelper,并把SqlReader改为OracleReader,把SqlParameter改为OracleSqlParameter,还有一两个也是Sql开头的,复制一个改为Oracle开头的就可以
五、EF
这个主要是改映射,碰到几个问题:
1、Oracle表名、列表均为大写,公司生成实体不是通过T4模板,而是有个存储过程,修改存储过程,加一个参数,如果传Oracle的话,就改为大写
[Table("XXX", Schema = "XXX")] public class Broker { /// <summary> /// BrokerID /// </summary> [Key] [Column("XXID")] public int xxID { get; set; }
2、或者可以在OnModelCreating里处理
protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<XXX>().Property(p => p.IsXX).HasColumnName("ISXXX").HasColumnType("odp_internal_use_type");base.OnModelCreating(modelBuilder); }
那个.Property和.HasColumnName,是为了处理列表转大写,可以在实体中使用[Column("XXX")]来实现,两种方法一样的。
3、bool型
[Column("ISXXX", Order = 0, TypeName = "odp_internal_use_type")] public bool? Isxxx { get; set; }
原先SQL是设计了bit型字段,对应的C#实体为bool。Oracle没有bit,会报错,一种是在OnModelCreating里写.HasColumnType("odp_internal_use_type")
或者在实体的属性里加
4、GUID类型
原先SQL里字段有uniqueidentifier类型,对应着实体为GUID,Oracle也没有对应的,默认生成RAW()型会报错,网上说RAW()是对应着byte[],还要转换。
最好的方法是Oracle使用VARCHAR2,实体使用string,然后定义个构造函数,实体初始化时这个字段生成一个新的GUID。
5、Schema
[Table("XXX", Schema = "XXX")]
一开始各种报错,后来搜了下,加上这个Schema就可以了
类似用户或库名(表空间),一般SQL是dbo,但可以不用管,Oracle要加上,但我明明在Web.Config里定义了用户名密码了,难道还要怎么定义下表空间吗?
因为现在各地库名是有带城市后缀的,比如xxxBJ(对应北京)、xxxSH(对应上海),如果转成Oracle,为了Schema一致,那以后表空间就只能一样了?要再研究一下。