Oracle 免费的数据库--Database 快捷版 11g 安装使用与"SOD框架"对Oracle的CodeFirst支持

一、Oracle XE 数据库与连接工具安装使用

Oracle数据库历来以价格昂贵出名,当然贵有贵的道理,成为一个Oracle DBA也是令人羡慕的事情,如果程序员熟悉Oracle使用也有机会接触到大型的项目,但是Oracle似乎对一般程序员不怎么友好,因为其繁琐的安装配置过程和对系统硬件的苛求,另一般人望而止步,我最早从Oracle 9i开始接触它,深有感受,特别是熟悉了SqlServer的开发人员,初次接触Oracle还是很不习惯的。比如它没有SqlServer数据“库”的概念,一个sa账号管理很多数据库,在Oracle里面,它叫做“数据服务”,通过不同的数据库用户来区分数据。

1.1 数据库服务安装

现在,Oracle推出了一个免费的数据库产品,Database 快捷版 11g ,这个就像SqlServer Express版本一样,都是免费的,与收费版在功能没有任何区别,但是有些使用条件限制,比如仅支持一个CPU,数据文件组大小有限制等,但是一般中小企业的一些中小应用还是够了。Database 快捷版 11g下载地址请点击这里。不过下载之前要先注册Oracle账号,并同意下载许可声明。

 

下载 适用于 Windows x64 的 Oracle Database 快捷版 11g 第 2 版
  - 解压缩下载文件,然后运行 DISK1/setup.exe
下载 适用于 Windows x32 的 Oracle Database 快捷版 11g 第 2 版
  - 解压缩下载文件,然后运行 DISK1/setup.exe
下载

适用于 Linux x64 的 Oracle Database 快捷版 11g 第 2 版 - 解压缩下载文件,可以像往常一样安装 RPM 文件

 根据你的情况,选择下载32位的或者64位的,我下载了64位的,安装很简单,中途没有什么特别注意的地方,一路“下一步” 即可,这比起Oracle其他版本的数据库安装来说,实在很简单,安装完成后,即可使用了,不过千万记住不要忘记了Sys,System 用户的密码。安装完成之后,在桌面会有一个快捷方式:Oracle Database 11g Express Edition 入门 ,单击,进入Web的管理界面:

如果要查看其它界面,需要输入管理员密码,比如查看存储的界面:

如果要进行创建数据库用户,建表等操作,还得启动SQL plus 程序,不用做额外的配置,可以直接启动,这相比收费版,又简单了不少:

具体创建用户,创建表的工作,可以使用Oracle的SQL语句来做,但我们这里通过另外一个工具来做,还是在之前的Oracle XE 下载页面:

  下载 Oracle SQL Developer
  下载 Oracle SQL Developer Data Modeler
  下载 Oracle Application Express
  下载 针对 Java 开发人员的 JDeveloper
  下载 Oracle Developer Tools for Visual Studio .NET
  下载 Zend Server

到这里下载一个最新版本的Oracle VS插件,有好几个版本,下载最上面的就好了,不过下载一样需要Oracle用户账号。

1.2 Oracle VS插件安装使用

安装这个插件的时候,注意安装提示,首先管理员账号Sys和密码,然后是要连接的Oracle服务名,输入相关的服务名,这里默认是 XE,然后保存为一个TNS名字,我用的是mydb,最后还有一个ODP.Net的安装,询问是否安装程序集到GAC,这里选择安装。

安装好后,在VS的“服务器资源管理器”--》“数据连接”,新建一个连接:

在图例中,我们选择以SysDba的角色进行登录,之后,就可以创建用户,查询表和编辑数据了,很方便,这里我建立了一个名字为SOD的用户,然后用这个用户登录:

功能很多,具体内容留给大家去研究了。不过从这里添加的用户不太方便设置成DBA角色,还是用命令行来设置。

至此,Oracle XE 的数据服务和开发工具插件,基本上安装好了。

1.3 PDF.NET集成开发工具连接Oracle

不过,我们也可以使用SOD框架的集成开发工具来连接,该工具连接过程如下:

最后点击确定,回到下面的界面,展开XE数据库,选择数据表,右键菜单查询数据:

 

至此,Oracle 的安装,连接过程就完成了,很简单。

二、SOD框架的Oracle CodeFirst支持

SOD框架是PDF.NET开发框架的数据框架,目前已经支持了SqlServer,SqlServerCe,Access,MySQL,PostgreSQL等主流数据库的Code First,但  PDF.NET_SOD Ver 5.2.1.0307  还未实现Oracle的Code First支持,主要原因是我对 Oracle 目前使用较少,如果不是SOD会员用户的强烈要求,可能SOD对Oracle Code First支持还要往后推延一段时间。

2.1 Oracle自增列处理

实际上SOD框架对Oracle Code First的支持并不复杂,主要需要解决的问题就是Oracle数据库自增字段的处理,大部分情况下,这都是通过触发器来实现的。

改写下 EntityCommand 类的创建表的方法,添加Oracle的处理:

 public string CreateTableCommand
        {
            get {
                if (_createTableCommand == null)
                {
                    string script = @"
CREATE TABLE @TABLENAME(
@FIELDS
)
";

                    if (this.currDb.CurrentDBMSType == PWMIS.Common.DBMSType.PostgreSQL && !string.IsNullOrEmpty(currEntity.IdentityName))
                    {
                        string seq =
                            "CREATE SEQUENCE " + currEntity.TableName + "_" + currEntity.IdentityName + "_" + "seq INCREMENT 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1;";

                        script = seq + script;
                    }
                    else if (this.currDb.CurrentDBMSType == PWMIS.Common.DBMSType.Oracle && !string.IsNullOrEmpty(currEntity.IdentityName))
                    {
                        // --; 语句分割符号
                        string seqTemp = @"

CREATE SEQUENCE @TableName_@IDName_SEQ MINVALUE 1 NOMAXVALUE INCREMENT BY 1 START WITH 1 NOCACHE
;--

CREATE OR REPLACE TRIGGER @TableName_INS_TRG BEFORE
  INSERT ON [@TableName] FOR EACH ROW WHEN(new.[@IDName] IS NULL)
BEGIN
  SELECT @TableName_@IDName_SEQ.NEXTVAL INTO :new.[@IDName] FROM DUAL; 
END;
;--
";
                        script = script + ";--\r\n" + seqTemp.Replace("@TableName", currEntity.TableName).Replace("@IDName", currEntity.IdentityName);
                    }

                    var entityFields = EntityFieldsCache.Item(this.currEntity.GetType());
                    string fieldsText = "";
                    foreach (string field in this.currEntity.PropertyNames)
                    {
                        string columnScript =entityFields.CreateTableColumnScript(this.currDb as AdoHelper, this.currEntity, field);
                        fieldsText = fieldsText + "," + columnScript+"\r\n";
                    }
                    string tableName =this.currDb.GetPreparedSQL("["+ currTableName+"]");
                    _createTableCommand = script.Replace("@TABLENAME", tableName).Replace("@FIELDS", fieldsText.Substring(1));
                }
                return _createTableCommand;
            }
        }

2.2 SOD Oracle Code First实现过程

由于Oracle 数据库的字段类型名称,对应DbType的名字并不完全相符,所以需要对AdoHelper类的Oracle实现类稍加修改:

public class Oracle : AdoHelper
{
  //其它略
        public override string GetNativeDbTypeName(IDataParameter para)
        {
            OracleParameter oraPara = (OracleParameter)para;
            OracleType oraType = oraPara.OracleType;
            if (oraType == OracleType.DateTime)
                return "Date";
            else if (oraType == OracleType.Int32)
                return "INT";
            else
                return oraType.ToString();
           
        }
}

能够根据实体类,得到生成表的建表脚本,任务已经完成了一半,不过SOD提供了一个DbContext类的封装,可以自动完成这个过程,下面就来实现一个Oracle的DbContext:

namespace PWMIS.Core.Extensions
{
    public abstract class OracleDbContext :DbContext
    {
        /// <summary>
        /// 用连接字符串名字初始化本类
        /// </summary>
        /// <param name="connName"></param>
        public OracleDbContext(string connName)
            : base(connName)
        { 
        
        }
        /// <summary>
        /// 检查实体类对应的数据表是否在数据库中存在
        /// </summary>
        protected override void CheckTableExists<T>()
        {
            //创建表
            if (CurrentDataBase.CurrentDBMSType == PWMIS.Common.DBMSType.Oracle)
            {
                var entity = new T();
                var dsScheme = CurrentDataBase.GetSchema("Tables", null);
                string owner = CurrentDataBase.ConnectionUserID;
                var rows = dsScheme.Select("OWNER='"+ owner +"' and table_name='" + entity.GetTableName() + "'");
                if (rows.Length == 0)
                {
                    EntityCommand ecmd = new EntityCommand(entity, CurrentDataBase);
                    string sql = ecmd.CreateTableCommand;
                    //OracleClient 不能批量执行多条SQL语句
                    string[] sqlArr = sql.Split(new string[] {";--" }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (string item in sqlArr)
                    {
                        if(item.Length >10) //去除回车行
                            CurrentDataBase.ExecuteNonQuery(item);
                    }
                   
                }
            }
        }
    }
}

2.3  Code First 使用示例

将SOD框架源码的 SampleORMTest 测试项目的LocalDbContext 的代码稍加修改:

namespace SampleORMTest
{
    /// <summary>
    /// 用来测试的本地SqlServer 数据库上下文类
    /// </summary>
    public class LocalDbContext : DbContext  //OracleDbContext, SqlServerDbContext 会根据 local连接字符串自动决定内部使用
    {
        public LocalDbContext()
            : base("local")
        {
            //local 是连接字符串名字
        }

        #region 父类抽象方法的实现

        protected override bool CheckAllTableExists()
        {
            //创建用户表
            CheckTableExists<User>();
            return true;
        }

        #endregion
    }
}

只需要在OracleDbContext 实现类的CheckAllTableExists 方法内,实现各个实体类的表创建工作即可,比如本例创建用户表。

修改下App.config 文件的连接配置:

 

<connectionStrings>
    <!--<add name="local" connectionString="Data Source=.;Initial Catalog=LocalDB;Integrated Security=True" providerName="SqlServer" />-->
    <!--下面的配置适应于 Oracle.Client-->
    <add name="local" connectionString="Data Source=XE;User Id=SOD;Password=sod123;Integrated Security=no;" providerName="Oracle" />
 </connectionStrings>

 然后,像下面这样使用,即可自动创建数据库和表,并且添加一条初始数据:

LocalDbContext context = new LocalDbContext();//自动创建表
User zhang_san = new User() { Name = "zhang san", Pwd = "123" };
            count += context.Add<User>(zhang_san);//采用 DbContext 方式插入数据

当然插入数据的方式很多,具体请看本文提供的源码下载。

最后,像下面这样使用查询即可:

User user = new User(){  Name="zhang san";};
OQL q=OQL.From(user)
  .Select()
  .Where(user.Name)
.END;
List<User> users = EntityQuery<User>.QueryList(OQL);

这种方式适合简单的相等条件查询,如果需要复杂的条件,可以修改成下面这个样子:

User user = new User();
OQL q = OQL.From(user)
              .Select()
              .Where(cmp => cmp.Comparer(user.Name, "=", "zhang san") )
            .END;
List<User> users = EntityQuery<User>.QueryList(q);

示例代码中的  可以修改成 >,<,like 等SQL支持的比较符号。

如果需要更多条件,可以使用 &表示SQL的AND,| 表示 SQL的OR 逻辑关系,比如:

User user = new User();
 OQL q = OQL.From(user)
               .Select()
               .Where(cmp => cmp.Comparer(user.Name, "=", "zhang san")  &
                             cmp.Comparer(user.Pwd, "=", "123")  )
             .END;

  

这样,一个简单的ORM使用实例就做好了。上面这段ORM例子,不仅仅适用于Oracle,使用在其它数据库都是可以得,只需要修改 连接字符串配置的 providerName和 connectionString 即可,比如 privideName="SqlServer"

 

三、使用ODP.Net 访问Oracle数据库

3.1 创建SOD的ODP.Net扩展程序集

在本文中,已经说到安装了Oracle 的.net数据访问组件ODP.Net,MS也建议用这个组件来代替MS自己的Oracle.Client,下面,我们只需要新建立一个项目,引用下ODP.Net组件即可:

把SOD框架的核心程序集PWMIS.Core 的Oracle.cs 文件拷贝下来,只需要修改下命名空间即可使用。

编译这个项目,让SampleORMTest 测试项目引用它,或者直接拷贝DLL到测试项目,

3.2 运行32位的ODP.Net

重新修改下App.config文件的连接配置:

<add name="local" connectionString="Data Source=XE;User Id=SOD;Password=sod123" 
         providerName="PWMIS.DataProvider.Data.OracleDataAccess.Oracle,PWMIS.OracleClient" />

运行项目,首先抛出下面这样一个异常:

其他信息: 未能加载文件或程序集“Oracle.DataAccess, Version=2.121.2.0, Culture=neutral, PublicKeyToken=89b483f429c47342”或它的某一个依赖项。试图加载格式不正确的程序。

第一反应,应该是32位于6位程序不兼容的问题,仔细回想下,这可能是 Oracle VS插件安装时候安装到GAC里面的程序集。于是将测试程序修改成32位的(编译目标为x86),运行良久,再次报错,说TNS无法解析。
奇怪,使用MS Oracle Client都没有问题,为何用了ODP.Net缺不行了呢?百度了下,但觉得别人说的跟我当前不太一样。

 检查Oracle的VS插件程序的安装目录,在 E:\app\client\dth\product\12.1.0\client_1\Network\Admin 目录中发现TSN配置文件 tnsnames.ora ,打开,原来是这样的内容:

mydb =
   (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = XE) 
    )
  )

分析内容,这应该是安装VS插件的时候,配置生成的。 那么原来的XE服务的监听名字是怎么来的? 在搜索下Oracle服务的安装目录,在 E:\oraclexe\app\oracle\product\11.2.0\server\network\ADMIN  下面找到了 tnsnames.ora 文件,打开:

XE =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = dth-home)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = XE)
    )
  )

EXTPROC_CONNECTION_DATA =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1))
    )
    (CONNECT_DATA =
      (SID = PLSExtProc)
      (PRESENTATION = RO)
    )
  )

ORACLR_CONNECTION_DATA = 
  (DESCRIPTION = 
    (ADDRESS_LIST = 
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1)) 
    ) 
    (CONNECT_DATA = 
      (SID = CLRExtProc) 
      (PRESENTATION = RO) 
    ) 
  ) 

原来默认的Oracle XE 监听服务名是这样定义的。

重新配置连接,将服务名从XE更改为mydb,顺利通过。

<add name="local" connectionString="Data Source=mydb;User Id=SOD;Password=sod123" 
 providerName="PWMIS.DataProvider.Data.OracleDataAccess.Oracle,PWMIS.OracleClient" />

如果不配置mydb这个TNS名字,可否直接使用呢?答案是可以,只需要将连接字符串做如下修改即可:

 <add name="local" connectionString="Data Source=(DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = XE) 
    )
  );User Id=SOD;Password=sod123"
        providerName="PWMIS.DataProvider.Data.OracleDataAccess.Oracle,PWMIS.OracleClient" />

测试运行,成功,可惜目前为止,还是基于32位的ODP.Net做的测试。

3.3 64位ODP.Net 使用

回忆之前安装XE数据库服务,确认当时安装的是64位的数据库,那么去它的安装目录,看看有没有ODP,一看,果然有:
E:\oraclexe\app\oracle\product\11.2.0\server\odp.net\bin\2.x
这里的 Oracle.DataAccess.dll 是64位的。
将它拷贝到SOD框架下面,再运行,终于看到了成功界面:

 

 

四、免安装Oracle客户端,使用ODP.Net

前面使用ODP.Net的过程,都是在本地机器安装了Oracle XE数据库和Oracle VS 开发插件的情况下进行的,但是,如果把访问Oracle的程序部署到一台没有装过Oracle程序的机器上,程序是无法使用的,这还得做下Oracle 环境的部署,过程如下:

4.1,下载ODAC

打开下面的链接:

http://www.oracle.com/technetwork/topics/dotnet/downloads/index-2235287.html?ssSourceSiteId=otncn


Oracle Data Access Components (12.1.0.1.0) Beta 2 - Oracle Universal Installer            [Released September 23, 2014]                                                                                 
 Download 32-bit ODAC
  Download ODAC121010Beta2_32bit.zip 291 MB (305,236,226 bytes)
     
     
 Download 64-bit ODAC
  Download ODAC121010Beta2_64bit.zip 282 MB (296,156,450 bytes)
     
     
    OUI Install and Configuration Instructions
   ODAC 12c Release 3 Beta 2 Installation Instructions
     

 


Oracle Data Access Components (12.1.0.1.0) Beta 2 - Xcopy           [Released September 23, 2014]                                    
 Download 32-bit ODAC
  Download ODAC121010Beta2_32bitXcopy.zip 61.6 MB (64,608,758 bytes)
     
     
 Download 64-bit ODAC
  Download ODAC121010Beta2_64bitXcopy.zip 65.8 MB (69,024,274 bytes)
     
     
 ODP.NET, Managed Driver
  Download ODP.NETManaged12010Beta2_Xcopy.zip 2.41 MB (2,532,077 bytes)
     

 这里提供了2种下载安装方式,前一种,Oracle Universal Installer  安装包比较大,略过,我们选择第二种,XCopy方式来部署。

根据你的需要,下载32位或者 64位的ODAC,并且下载 ODP.Net ,Managed Driver.

4.2,安装ODAC

比如我下载的是 64位的ODAC,以管理员权限启动命令行

第一步,输入下面的命令:

install.bat all c:\oracle odac

这里表示将Oracle客户端程序复制到 c:\oracle 目录下面

第二步,安装ODP.Net,输入下面的命令:

install_odpm.bat c:\oracle x64 true

注意:c:\oracle 目录是第一步命令里面指定的路径。

第三步,关键,在系统环境变量里面,Path变量里面,包含Oracle程序的路径:

c:\oracle;c:\oracle\bin;

这样设置以后,本文的Oracle访问程序,就可以正常运行了。

 

五、获取Oracle SOD Code First支持

当前程序的全部代码已经签入SOD框架的开源项目,地址 http://pwmis.codeplex.com ,你在源码栏目可以查看到当前最新的更改,如果你有codeplex账号,可以直接连接TFS下载,如果没有,可以用SVN下载,独立下载包,

Application     Oracle_ORM_Sample

Application     PDFNetTools20150324

下载说明,请看 https://pwmis.codeplex.com/releases/view/612310

 如果你们有Oracle服务器,但不再本地机器,可能需要单独下载ODP并安装, 64位程序下载地址:http://www.oracle.com/technetwork/database/windows/downloads/index-090165.html

 

SOD框架开发团队一直致力于广大程序员的CRUD解放工作,打造最轻,最方便而又灵活的数据开发框架,感谢你的支持!

欢迎加入SOD开发者团队,更多详细信息,请看框架官网 http://www.pwmis.com/sqlmap

posted on 2015-03-23 23:52  深蓝医生  阅读(23986)  评论(13编辑  收藏  举报

导航