Oracle數據庫歷來以價格昂貴出名,當然貴有貴的道理,成為一個Oracle DBA也是令人羨慕的事情,如果程序員熟悉Oracle使用也有機會接觸到大型的項目,但是Oracle似乎對一般程序員不怎麼友好,因為其繁瑣的安裝配置過程和對系統硬件的苛求,另一般人望而止步,我最早從Oracle 9i開始接觸它,深有感受,特別是熟悉了SqlServer的開發人員,初次接觸Oracle還是很不習慣的。比如它沒有SqlServer數據“庫”的概念,一個sa賬號管理很多數據庫,在Oracle裡面,它叫做“數據服務”,通過不同的數據庫用戶來區分數據。
現在,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 VS插件,有好幾個版本,下載最上面的就好了,不過下載一樣需要Oracle用戶賬號。
安裝這個插件的時候,注意安裝提示,首先管理員賬號Sys和密碼,然後是要連接的Oracle服務名,輸入相關的服務名,這裡默認是 XE,然後保存為一個TNS名字,我用的是mydb,最後還有一個ODP.Net的安裝,詢問是否安裝程序集到GAC,這裡選擇安裝。
安裝好後,在VS的“服務器資源管理器”--》“數據連接”,新建一個連接:

在圖例中,我們選擇以SysDba的角色進行登錄,之後,就可以創建用戶,查詢表和編輯數據了,很方便,這裡我建立了一個名字為SOD的用戶,然後用這個用戶登錄:

功能很多,具體內容留給大家去研究了。不過從這裡添加的用戶不太方便設置成DBA角色,還是用命令行來設置。
至此,Oracle XE 的數據服務和開發工具插件,基本上安裝好了。
不過,我們也可以使用SOD框架的集成開發工具來連接,該工具連接過程如下:

最後點擊確定,回到下面的界面,展開XE數據庫,選擇數據表,右鍵菜單查詢數據:

至此,Oracle 的安裝,連接過程就完成了,很簡單。
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支持還要往後推延一段時間。
實際上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;
}
}
由於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);
}
}
}
}
}
}
將SOD框架源碼的 SampleORMTest 測試項目的SqlServerDbContext 改成OracleDbContext的:
namespace SampleORMTest
{
/// <summary>
/// 用來測試的本地SqlServer 數據庫上下文類
/// </summary>
public class LocalDbContext : OracleDbContext // SqlServerDbContext
{
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>
在本文中,已經說到安裝了Oracle 的.net數據訪問組件ODP.Net,MS也建議用這個組件來代替MS自己的Oracle.Client,下面,我們只需要新建立一個項目,引用下ODP.Net組件即可:

把SOD框架的核心程序集PWMIS.Core 的Oracle.cs 文件拷貝下來,只需要修改下命名空間即可使用。
編譯這個項目,讓SampleORMTest 測試項目引用它,或者直接拷貝DLL到測試項目,
重新修改下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做的測試。
回憶之前安裝XE數據庫服務,確認當時安裝的是64位的數據庫,那麼去它的安裝目錄,看看有沒有ODP,一看,果然有:
E:\oraclexe\app\oracle\product\11.2.0\server\odp.net\bin\2.x
這裡的 Oracle.DataAccess.dll 是64位的。
將它拷貝到SOD框架下面,再運行,終於看到了成功界面:

前面使用ODP.Net的過程,都是在本地機器安裝了Oracle XE數據庫和Oracle VS 開發插件的情況下進行的,但是,如果把訪問Oracle的程序部署到一台沒有裝過Oracle程序的機器上,程序是無法使用的,這還得做下Oracle 環境的部署,過程如下:
打開下面的鏈接:
http://www.oracle.com/technetwork/topics/dotnet/downloads/index-2235287.html?ssSourceSiteId=otncn
這裡提供了2種下載安裝方式,前一種,Oracle Universal Installer 安裝包比較大,略過,我們選擇第二種,XCopy方式來部署。
根據你的需要,下載32位或者 64位的ODAC,並且下載 ODP.Net ,Managed Driver.
比如我下載的是 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訪問程序,就可以正常運行了。
當前程序的全部代碼已經簽入SOD框架的開源項目,地址 http://pwmis.codeplex.com ,你在源碼欄目可以查看到當前最新的更改,如果你有codeplex賬號,可以直接連接TFS下載,如果沒有,可以用SVN下載,獨立下載包,
打造最輕,最方便而又靈活的數據開發框架,感謝你的支持!
歡迎加入SOD開發者團隊,更多詳細信息,請看框架官網 http://www.pwmis.com/sqlmap