在.NetCore(C#)中使用ODP.NET Core+Dapper操作Oracle資料庫

曦遠發表於2021-02-04

前言

雖然一直在說“去IOE化”,但是在國企和政府,Oracle的歷史包袱實在太重了,甚至很多業務邏輯都是寫在Oracle的各種儲存過程裡面實現的……

我們的系統主要的技術棧是Django / Spring / AspNetCore,Java的不必說對Oracle支援肯定沒問題,關鍵在於Django對Oracle版本有要求,相容性不是特別好,Oracle版本沒辦法隨意升級的,所以我想到用.Net Core來寫個中間層,讓其他系統可以方便的使用Oracle的資料和儲存過程…

ODP.NET Core是一個ADO.NET驅動程式,提供從Microsoft .NET Core客戶端到Oracle資料庫的快速資料訪問。它可以在Windows和Linux上執行。ODP.NET由一個100%託管程式碼動態連結庫Oracle.ManagedDataAccess.dll組成,可通過NuGet安裝獲得。

這個Oracle.ManagedDataAccess.Core是真的方便,不用安裝Oracle客戶端,相容性、便捷性,反正就是開箱即用,一把梭就完事了

簡單使用

首先用nuget安裝這個Oracle.ManagedDataAccess.Core,之後就可以執各類操作了,不過從程式碼量上看還是比較繁瑣的,上程式碼:

var connStr = $"DATA SOURCE=127.0.0.1/db_name; PASSWORD=password; PERSIST SECURITY INFO=True; USER ID=user_id";
using (var conn = new OracleConnection(connStr)) {
    using (var command = conn.CreateCommand()) {
        try {
            if (conn.State == ConnectionState.Closed) {
                conn.Open();
            }

            command.BindByName = true;
            command.CommandText = $"select * from table_name";

            using (var reader = command.ExecuteReader()) {
                while (reader.Read()) {
                    Console.WriteLine(reader.GetString("DEPART_NAME"));
                }
            }
        }
        catch (Exception ex) {
            Console.WriteLine(ex.StackTrace);
            Console.WriteLine(ex.Source);
            Console.WriteLine(ex.Message);
        }
    }
}

這就是執行select * from table_name這條SQL語句的程式碼,有點長…… 吐了

再看看執行儲存過程的…

var connStr = $"DATA SOURCE=127.0.0.1/db_name; PASSWORD=password; PERSIST SECURITY INFO=True; USER ID=user_id";
using (var conn = new OracleConnection(connStr)) {
    conn.Open();
    var command = new OracleCommand("proc_name", conn) {
        CommandType = CommandType.StoredProcedure
    };

    // 輸入引數
    command.Parameters.Add(new OracleParameter("id", "0001"));

    // 輸出引數
    var vOut = new OracleParameter("v_out",
        OracleDbType.Varchar2,
        1000,
        "",
        ParameterDirection.InputOutput
    );

    command.Parameters.Add(vOut);

    var affectRows = command.ExecuteNonQuery();

    Console.WriteLine(vOut.Value);
}

這裡去掉了錯誤處理,顯得短一點,不過還是麻煩得不行……

所以這裡我們要用Dapper這個輕量級ORM來簡化操作

使用Dapper

不多說,首先nuget安裝是常規操作,包名就是簡單的Dapper

首先是增刪改查這類普通的SQL語句:

using Dapper;

var connStr = $"DATA SOURCE=127.0.0.1/db_name; PASSWORD=password; PERSIST SECURITY INFO=True; USER ID=user_id";
using var cn = new OracleConnection(connStr);

var result = cn.Query("select * from table_name");

foreach (var item in result) {
    Console.WriteLine(item);
}

可以看到引入Dapper之後只要使用OracleConnection的擴充套件方法Query來執行SQL就行了~ 返回的結果是IEnumerable<dynamic>型別,當然你也可以在Query方法的泛型引數裡指定返回的型別,我這裡為了通用就不指定了

繼續看儲存過程的,很簡單,更上面的差不多,就多一個引數告訴程式我們的SQL型別是啥而已

var connStr = $"DATA SOURCE=127.0.0.1/db_name; PASSWORD=password; PERSIST SECURITY INFO=True; USER ID=user_id";
using var cn = new OracleConnection(connStr);

var result = cn.Query("proc_name", commandType: CommandType.StoredProcedure);

foreach (var item in result) {
    Console.WriteLine(item);
}

如果是有帶引數的儲存過程咋辦?

很簡單(程式碼來自官方例子)~

var user = cnn.Query<User>("spGetUser", new {Id = 1},
        commandType: CommandType.StoredProcedure).SingleOrDefault();

ok,很方便,更多操作看Dapper文件就完事了(我也是第一次接觸Dapper,之前都用FreeSQL和EFCore),此文完結~

Dapper專案主頁:https://github.com/StackExchange/Dapper

參考資料

相關文章