[譯]ASP.NET Core Web API 中使用Oracle數(shù)據(jù)庫和Dapper看這篇就夠了

[譯]ASP.NET Core Web API 中使用Oracle數(shù)據(jù)庫和Dapper看這篇就夠了

本文首發(fā)自:博客園

文章地址: https://www.cnblogs.com/yilezhu/p/9276565.html

園子里關(guān)于ASP.NET Core Web API的教程很多,但大多都是使用EF+Mysql或者EF+MSSQL的文章。甚至關(guān)于ASP.NET Core Web API中使用Dapper+Mysql組合的文章都很少,更別提Oracel+Dapper組合的文章了,那么今天就帶著大家一起翻譯一篇國外大牛寫的關(guān)于ASP.NET Core Web API 開發(fā)中使用Oracle+Dapper的組合的文章吧。

注:雖然本文內(nèi)容是翻譯,但是樓主剛在2.1環(huán)境是使用成功,中間也沒有任何阻礙,只是鑒于本人電腦配置太差無法安裝Oracle數(shù)據(jù)庫,所以無法進(jìn)行演示,再者是表示對原作者的尊重,所以在這里只是對原作內(nèi)容進(jìn)行翻譯然后加上自己的理解稍作改動。應(yīng)該能對大家使用Oracle+Dapper組合開發(fā)ASP.NET Core Web API 有所幫助。

本文的重點(diǎn)是介紹如何使用Dapper ORM+Oracle數(shù)據(jù)庫的組合來創(chuàng)建ASP.NET Core Web API。首先,在這里,我們不使用SQL ,因?yàn)榛ヂ?lián)網(wǎng)上已有很多文章都是使用SQL Server進(jìn)行演示的。所以,我想寫一篇使用Oracle作為數(shù)據(jù)庫的文章。為了降低數(shù)據(jù)庫訪問邏輯的復(fù)雜性,我們使用Dapper ORM。那么,讓我們趕緊開始實(shí)戰(zhàn)演練吧。

創(chuàng)建一個(gè)ASP.NET Core Web API 項(xiàng)目

如果要創(chuàng)建一個(gè)新的ASP.NET Core Web API項(xiàng)目的話,只需要打開Visual Studio 2017版本15.3及以上,然后按照以下步驟操作。

  1. 打開文件菜單,點(diǎn)擊新建>>項(xiàng)目
  2. 在新打開的新建項(xiàng)目窗口,首先你需要選擇 .NET Framework 4.6及以上版本,然后在左側(cè)面板選擇C# ,然后選擇 .NET Core
  3. 在右側(cè)面板中選擇“.NET Core Web 應(yīng)用程序” 并且選擇項(xiàng)目位置,最后點(diǎn)擊“確定”
  4. 在下一個(gè)窗口,在眾多模板中選擇Web API模板

寫如何新建ASP.NET Core Web API 的這些步驟的時(shí)候我都嫌累,我想大家應(yīng)該都知道怎么創(chuàng)建吧!就不上圖片了。

設(shè)置Oracle表和存儲過程

首先要為演示創(chuàng)建數(shù)據(jù)庫以及表,我們這里使用Oracle Developer Tools。因?yàn)樗浅P∏伸`活,可以幫助我們順利的處理Oracle數(shù)據(jù)庫。
Oracle SQL Developer是一個(gè)免費(fèi)的集成開發(fā)環(huán)境,可簡化傳統(tǒng)和云部署中Oracle數(shù)據(jù)庫的開發(fā)和管理。SQL Developer提供完整的PL / SQL應(yīng)用程序端到端開發(fā),運(yùn)行查詢和腳本的工作表,用于管理數(shù)據(jù)庫的DBA控制臺,報(bào)告界面,完整的數(shù)據(jù)建模解決方案以及用于遷移第三方數(shù)據(jù)到Oracle的平臺。
創(chuàng)建一個(gè)名為“TEST_DB”的數(shù)據(jù)庫名稱,并在其中創(chuàng)建一個(gè)表名為“EMPLOYEE”。您可以使用以下語法在“TEST_DB”數(shù)據(jù)庫中創(chuàng)建表。

 CREATE TABLE "TEST_DB"."EMPLOYEE"   
  (   
   "ID" NUMBER(10,0) GENERATED BY DEFAULT ON NULL AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 100 CACHE 20 NOORDER  NOCYCLE ,   
"NAME" VARCHAR2(255 BYTE),   
"SALARY" NUMBER(10,0),   
"ADDRESS" VARCHAR2(500 BYTE)  
  ) SEGMENT CREATION IMMEDIATE   
 PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255   
NOCOMPRESS LOGGING  
 STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645  
 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1  
 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)  
 TABLESPACE "TEST_DATA" ;  

我們需要在表中添加一些虛擬數(shù)據(jù),以便我們可以直接從PostMan獲取數(shù)據(jù)。所以,我們在這里添加四條記錄如下。

Insert into TEST_DB.EMPLOYEE (ID,NAME,SALARY,ADDRESS) values (100,'Mukesh',20000,'India');  
Insert into TEST_DB.EMPLOYEE (ID,NAME,SALARY,ADDRESS) values (101,'Rion',28000,'US');  
Insert into TEST_DB.EMPLOYEE (ID,NAME,SALARY,ADDRESS) values (102,'Mahesh',10000,'India');  
Insert into TEST_DB.EMPLOYEE (ID,NAME,SALARY,ADDRESS) values (103,'Banky',20000,'India'); 

現(xiàn)在我們來創(chuàng)建一個(gè)存儲過程,用來獲取員工記錄列表。這里我們使用Cursor返回?cái)?shù)據(jù)列表作為輸出參數(shù)。

CREATE OR REPLACE PROCEDURE "TEST_DB"."USP_GETEMPLOYEES" (  
    EMPCURSOR OUT SYS_REFCURSOR  
)  
AS  
Begin  
Open EMPCURSOR For  
SELECT ID, NAME, SALARY,ADDRESS FROM Employee;  
End; 

下面我們再創(chuàng)建一個(gè)存儲過程,它根據(jù)員工ID獲取員工的個(gè)人記錄

CREATE OR REPLACE PROCEDURE "TEST_DB"."USP_GETEMPLOYEEDETAILS"   
(  
  EMP_ID IN INT,  
  EMP_DETAIL_CURSOR OUT SYS_REFCURSOR    
) AS   
BEGIN  
    OPEN EMP_DETAIL_CURSOR FOR  
    SELECT ID, NAME, SALARY,ADDRESS FROM Employee WHERE ID = EMP_ID;  
END;  

安裝Dapper ORM

從“工具”菜單的“Nuget包管理器”中打開“包管理器控制臺”,然后輸入以下命令并按Enter鍵以安裝dapper及其依賴項(xiàng)(如果有)

Install-Package Dapper -Version 1.50.5
當(dāng)然還有另一個(gè)安裝方式,具體可以看 [ASP.NET Core WebApi使用Swagger生成api說明文檔看這篇就夠了][http://www.cnblogs.com/yilezhu/p/9241261.html] 中關(guān)于安裝Swashbuckle.AspNetCore的步驟
安裝完成后,你可以查看下項(xiàng)目大的引用中,是否有“Dapper”的引用,如果有的話表示安裝正確

為項(xiàng)目安裝Oracle Manage Data Access

我們在Asp.Net Core Web API應(yīng)用程序中使用Oracle,需要從Core應(yīng)用程序訪問Oracle數(shù)據(jù)庫。要將Oracle數(shù)據(jù)庫與.Net Core應(yīng)用程序一起使用,我們有Oracle庫,它將幫助我們管理數(shù)據(jù)庫訪問的邏輯。因此,我們必須安裝以下bata的軟件包。

Install-Package Oracle.ManagedDataAccess.Core -Version 2.12.0-beta2

添加 Oracle 數(shù)據(jù)庫連接

現(xiàn)在我們已準(zhǔn)備好與數(shù)據(jù)庫相關(guān)的所有內(nèi)容,如數(shù)據(jù)庫,表和SP等。要從Web API訪問數(shù)據(jù)庫,我們必須像往常一樣在“appsettings.json”文件中創(chuàng)建連接字符串。

{  
  "Logging": {  
    "IncludeScopes": false,  
    "Debug": {  
      "LogLevel": {  
        "Default": "Warning"  
      }  
    },  
    "Console": {  
      "LogLevel": {  
        "Default": "Warning"  
      }  
    }  
  },  
  "ConnectionStrings": {  
    "EmployeeConnection": "data source=mukesh:1531;password=**********;user id=mukesh;Incr Pool Size=5;Decr Pool Size=2;"  
  }  
}  

創(chuàng)建一個(gè)倉儲

為了保持關(guān)注點(diǎn)的分離,我們在這里使用Repository。在Web API項(xiàng)目中創(chuàng)建一個(gè)新文件夾作為“倉儲庫”,并創(chuàng)建一個(gè)“IEmployeeRepository”接口和一個(gè)它的實(shí)現(xiàn)類“EmployeeRepository”,它將實(shí)現(xiàn)到IEmployeeRepository。

namespace Core2API.Repositories  
{  
    public interface IEmployeeRepository  
    {  
        object GetEmployeeList();  
  
        object GetEmployeeDetails(int empId);  
          
    }  
}  

以下是實(shí)現(xiàn)了IEmployeeRepository的EmployeeRepository類。它需要訪問配置中的數(shù)據(jù)庫連接串,因此我們在構(gòu)造函數(shù)中注入IConfiguration。所以,我們已經(jīng)準(zhǔn)備好使用配置對象了。除此之外,我們還有GetConnection()方法,該方法將從appsettings.json獲取連接字符串,并將其提供給OracleConnection以創(chuàng)建連接并最終返回連接。我們已經(jīng)實(shí)現(xiàn)了“IEmployeeRepository”,它有兩個(gè)方法,如GetEmployeeDetails和GetEmployeeList。

using Core2API.Oracle;  
using Dapper;  
using Microsoft.Extensions.Configuration;  
using Oracle.ManagedDataAccess.Client;  
using System;  
using System.Data;  
  
  
namespace Core2API.Repositories  
{  
    public class EmployeeRepository : IEmployeeRepository  
    {  
        IConfiguration configuration;  
        public EmployeeRepository(IConfiguration _configuration)  
        {  
            configuration = _configuration;  
        }  
        public object GetEmployeeDetails(int empId)  
        {  
            object result = null;  
            try  
            {  
                var dyParam = new OracleDynamicParameters();  
                dyParam.Add("EMP_ID", OracleDbType.Int32, ParameterDirection.Input, empId);  
                dyParam.Add("EMP_DETAIL_CURSOR", OracleDbType.RefCursor, ParameterDirection.Output);  
  
                var conn = this.GetConnection();  
                if (conn.State == ConnectionState.Closed)  
                {  
                    conn.Open();  
                }  
  
                if (conn.State == ConnectionState.Open)  
                {  
                    var query = "USP_GETEMPLOYEEDETAILS";  
  
                    result = SqlMapper.Query(conn, query, param: dyParam, commandType: CommandType.StoredProcedure);  
                }  
            }  
            catch (Exception ex)  
            {  
                throw ex;  
            }  
  
            return result;  
        }  
  
        public object GetEmployeeList()  
        {  
            object result = null;  
            try  
            {  
                var dyParam = new OracleDynamicParameters();  
  
                dyParam.Add("EMPCURSOR", OracleDbType.RefCursor, ParameterDirection.Output);  
  
                var conn = this.GetConnection();  
                if(conn.State == ConnectionState.Closed)  
                {  
                    conn.Open();  
                }  
  
                if (conn.State == ConnectionState.Open)  
                {  
                    var query = "USP_GETEMPLOYEES";  
  
                    result = SqlMapper.Query(conn, query, param: dyParam, commandType: CommandType.StoredProcedure);  
                }  
            }  
            catch (Exception ex)  
            {  
                throw ex;  
            }  
  
            return result;  
        }  
  
        public IDbConnection GetConnection()  
        {  
            var connectionString = configuration.GetSection("ConnectionStrings").GetSection("EmployeeConnection").Value;  
            var conn = new OracleConnection(connectionString);             
            return conn;  
        }  
    }  
}  
   
public IDbConnection GetConnection()  
{  
     var connectionString = configuration.GetSection("ConnectionStrings").GetSection("EmployeeConnection").Value;  
     var conn = new OracleConnection(connectionString);             
     return conn;  
}  

為了在.Net Core中使用Oracle的數(shù)據(jù)類型,我們使用的是OracleDyamicParameters類,它將提供管理Oracle參數(shù)行為的一系列方法。

using Dapper;  
using Oracle.ManagedDataAccess.Client;  
using System.Collections.Generic;  
using System.Data;  
  
namespace Core2API.Oracle  
{  
    public class OracleDynamicParameters : SqlMapper.IDynamicParameters  
    {  
        private readonly DynamicParameters dynamicParameters = new DynamicParameters();  
        private readonly List<OracleParameter> oracleParameters = new List<OracleParameter>();  
  
        public void Add(string name, OracleDbType oracleDbType, ParameterDirection direction, object value = null, int? size = null)  
        {  
            OracleParameter oracleParameter;  
            if (size.HasValue)  
            {  
                oracleParameter = new OracleParameter(name, oracleDbType, size.Value, value, direction);  
            }  
            else  
            {  
                oracleParameter = new OracleParameter(name, oracleDbType, value, direction);  
            }  
  
            oracleParameters.Add(oracleParameter);  
        }  
  
        public void Add(string name, OracleDbType oracleDbType, ParameterDirection direction)  
        {  
            var oracleParameter = new OracleParameter(name, oracleDbType, direction);  
            oracleParameters.Add(oracleParameter);  
        }  
  
        public void AddParameters(IDbCommand command, SqlMapper.Identity identity)  
        {  
            ((SqlMapper.IDynamicParameters)dynamicParameters).AddParameters(command, identity);  
  
            var oracleCommand = command as OracleCommand;  
  
            if (oracleCommand != null)  
            {  
                oracleCommand.Parameters.AddRange(oracleParameters.ToArray());  
            }  
        }  
    }  
}  

在Startup.cs中配置依賴

如果要在控制器或倉儲類中使用依賴項(xiàng)的話,我們必須配置或者說在Startup類的ConfigureServices方法中為我們的接口注冊我們的依賴項(xiàng)類。 (翻譯的好拗口,樓主四級沒過,希望不被噴)

using Core2API.Repositories;  
using Microsoft.AspNetCore.Builder;  
using Microsoft.AspNetCore.Hosting;  
using Microsoft.Extensions.Configuration;  
using Microsoft.Extensions.DependencyInjection;  
  
namespace Core2API  
{  
    public class Startup  
    {  
        public Startup(IConfiguration configuration)  
        {  
            Configuration = configuration;  
        }  
  
        public IConfiguration Configuration { get; }  
  
        // This method gets called by the runtime. Use this method to add services to the container.  
        public void ConfigureServices(IServiceCollection services)  
        {  
            services.AddTransient<IEmployeeRepository, EmployeeRepository>();  
            services.AddSingleton<IConfiguration>(Configuration);  
            services.AddMvc();  
        }  
  
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.  
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)  
        {  
            if (env.IsDevelopment())  
            {  
                app.UseDeveloperExceptionPage();  
            }  
  
            app.UseMvc();  
        }  
    }  
}  

添加 EmployeeController 控制器

現(xiàn)在是時(shí)候在EmployeeControler中創(chuàng)建API調(diào)用了。首先,我們在構(gòu)造函數(shù)中添加了IEmployeeRepository以使用依賴項(xiàng)。其次,我們必須為兩個(gè)方法創(chuàng)建帶有Route屬性的API調(diào)用。

using Core2API.Repositories;  
using Microsoft.AspNetCore.Mvc;  
  
namespace CoreAPI.Controllers  
{  
    [Produces("application/json")]      
    public class EmployeeController : Controller  
    {  
        IEmployeeRepository employeeRepository;  
        public EmployeeController(IEmployeeRepository _employeeRepository)  
        {  
            employeeRepository = _employeeRepository;  
        }  
  
        [Route("api/GetEmployeeList")]  
        public ActionResult GetEmployeeList()  
        {  
            var result = employeeRepository.GetEmployeeList();  
            if (result == null)  
            {  
                return NotFound();  
            }  
            return Ok(result);              
        }  
  
        [Route("api/GetEmployeeDetails/{empId}")]  
        public ActionResult GetEmployeeDetails(int empId)  
        {  
            var result = employeeRepository.GetEmployeeDetails(empId);  
            if (result == null)  
            {  
                return NotFound();  
            }  
            return Ok(result);  
        }  
    }  
}  

現(xiàn)在我們已準(zhǔn)備就緒,就像存儲庫已準(zhǔn)備好,與Oracle數(shù)據(jù)庫的連接已準(zhǔn)備就緒,最后,API調(diào)用也在控制器內(nèi)部就緒。因此,是時(shí)候在PostMan中運(yùn)行API來查看結(jié)果了。只需按F5即可運(yùn)行Web API然后打開PostMan進(jìn)行測試。

要在PostMan中進(jìn)行測試,首先選擇“Get”作為方法,并提供URL以獲取員工記錄列表,然后單擊“發(fā)送”按鈕,該按鈕將向我們的API發(fā)出請求并使用我們文章開始時(shí)創(chuàng)建的數(shù)據(jù)庫腳本來獲取我們在此處添加的員工列表數(shù)據(jù)。

ASP.NET Core Web Api

要獲取單個(gè)員工記錄,只需傳遞以下URL,如圖中所示。您可以在此處看到,我們希望查看員工ID 103的記錄。發(fā)送請求后,您可以看到如下所示的輸出。

ASP.NET Core

最后

所以,今天,我們已經(jīng)學(xué)會了如何創(chuàng)建ASP.NET Core Web API項(xiàng)目并使用Dapper與Oracle數(shù)據(jù)庫一起使用。

我希望這篇文章能對你有所幫助。請使用評論來進(jìn)行反饋,這有助于我提高自己的下一篇文章。如果您有任何疑問,請?jiān)谠u論部分發(fā)表你的疑問,如果您喜歡這篇文章,請與您的朋友分享。并記得點(diǎn)下推薦哦!

原文地址:https://www.c-sharpcorner.com/article/asp-net-core-web-api-with-oracle-database-and-dapper/
翻譯人:依樂祝

總結(jié)

今天主要是翻譯了一篇國外的使用Dapper以及Oracle的組合來開發(fā)asp.net core web api的教程!目的就是填補(bǔ)園子里使用Dapper以及Oracle的組合來開發(fā)asp.net core web api的空白!還有就是最近連續(xù)出差都沒有更新文章了!接下來我會為大家介紹更多asp.net core 微服務(wù)相關(guān)的技術(shù),希望大家持續(xù)關(guān)注!如果感覺博主寫的還不錯(cuò)的話希望給個(gè)推薦!謝謝!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,002評論 6 542
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,400評論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,136評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,714評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,452評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,818評論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,812評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,997評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,552評論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,292評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,510評論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,721評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,121評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,429評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,235評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,480評論 2 379

推薦閱讀更多精彩內(nèi)容