.NET Core中使用Dapper操作Oracle儲存過程最佳實踐
為什麼說是最佳實踐呢?因為在實際開發中踩坑了,而且發現網上大多數文章給出的解決方法都不能很好地解決問題。尤其是在獲取型別為OracleDbType.RefCursor
,輸出為:ParameterDirection.Output
資料的時候。網上千篇一律的說寫一個OracleDynamicParameters
的擴充套件。但是給出的程式碼 OracleDynamicParameters
中對於Get
方法都沒有貼出程式碼或者Get
方法的書寫存在一定的問題。這就導致了,如果你執行一個Oracle儲存過程並且獲取OracleDbType.RefCursor
型別的輸出值的時候就會爆“OracleDbType無法轉換成CLR型別”的問題。具體的異常提示這裡就不截圖了,大致就是需要進行一下OracleDbType
到CLR型別的一個轉換。
Dapper的DynamicParameters不支援遊標型別
如果你用Dapper來進行Oracle的儲存過程的操作,剛好這個儲存過程需要傳入一個遊標型別的輸出值,如下所示,你會發現在DbType
中是不包含遊標型別的。
var p = new DynamicParameters(); p.Add("foo", "bar"); p.Add("baz_cursor", dbType: DbType.?(沒有遊標型別) , direction: ParameterDirection.Output);
自定義OracleDynamicParameters來支援遊標型別
不知道大家還有咩有印象,我在2018年的時候曾經翻譯了一篇關於在.NET Core中使用Dapper操作Oracle的文章,沒有印象的可以點選連結檢視下[。
這篇文章是翻譯的,裡面有一個OracleDynamicParameters
的擴充套件方法的程式碼,具體的程式碼大家可以點選上面的連結進行檢視,使用這個OracleDynamicParameters
進行Oracle儲存過程的查詢是不會有問題的,而且也支援包含OracleDbType.RefCursor
型別的儲存過程的執行。因為它在Add
引數的時候傳入的是資料型別是OracleDbType
型別,如下所示:
因此這裡我們可以在新增引數的時候,傳入遊標型別了。如下所示:
但是這時候,如果這個遊標型別是輸出引數,這時候你如果透過下面這種方式來直接獲取的話,就會爆我們文章開頭的錯誤了。
異常的大概意思就是“返回的是OracleDbType型別,沒法直接轉換成CLR型別,如上面的int型別”。
解決異常問題
既然知道了異常的問題,那麼接下來我們就需要解決這個問題了。大概的解決思路也就是重新實現下Get<T>
方案,在獲取資料的時候執行下OracleDataType到CLR型別的轉換。可能這個對大夥有點難度,但是別擔心,我們有GayHub,因此我在GayHub上果然找到了現成的實現,具體的程式碼可以 這裡實現的OracleDynamicParameters
比我們實現的更強大,功能也更豐富。同時也實現了Get<T>
方法的轉換。如下圖所示:
同時,作者也釋出了Nuget包,來讓你遠離996.使用方式如下:
然後在檔案中引入Dapper.Oracle
的明明空間就可以了。
同時此專案的GitHub地址有必要貼一下:
正如作者所說:此程式集新增了對編寫Oracle特定SQL的支援,該SQL支援Oracle託管提供程式對引數使用的所有DbType,支援對命令設定各種屬性(lobfetchsize、arraybindcount、bindbyname),以及對引數設定collectiontype。使用此包,現在可以執行返回refcursor的儲存過程,或者使用陣列繫結計數來執行帶有引數陣列的SQL語句。
最後
今天給大家分享了一個我們.NET Core中使用Dapper操作Oracle儲存過程遇到的坑,同時給出了個人認為是最佳實現的解決方法。希望對大家有所幫助。Dapper是一個好的工具,可以讓你編寫高效能的資料庫操作程式碼。但是,有時在對Oracle的支援上,可能有一些欠缺,這時候就有一批樂於分享,甘於貢獻的程式設計愛好者來分享優秀的擴充套件來讓我們遠離996.
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/506/viewspace-2822773/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle儲存過程Oracle儲存過程
- Oracle儲存過程-1Oracle儲存過程
- oracle的儲存過程Oracle儲存過程
- Oracle儲存過程乾貨(一):儲存過程基礎Oracle儲存過程
- Dapper in .Net CoreAPP
- 在.NetCore(C#)中使用ODP.NET Core+Dapper操作Oracle資料庫NetCoreC#APPOracle資料庫
- 原創:oracle 儲存過程Oracle儲存過程
- Sqlsugar呼叫Oracle的儲存過程SqlSugarOracle儲存過程
- LightDB/PostgreSQL 相容Oracle儲存過程SQLOracle儲存過程
- oracle儲存過程書寫格式Oracle儲存過程
- MySQL儲存過程中如何使用ROLLBACKMySql儲存過程
- mysql儲存過程及日期函式實踐MySql儲存過程函式
- MySQL 中儲存時間的最佳實踐MySql
- PetaPoco在.net專案中的簡單使用(儲存過程篇)儲存過程
- 使用JavaScript和Python實現Oracle資料庫的儲存過程?JavaScriptPythonOracle資料庫儲存過程
- Azure Storage 系列(二) .NET Core Web 專案中操作 Blob 儲存Web
- Oracle儲存過程中定義多個遊標Oracle儲存過程
- Oracle儲存過程中跳出迴圈的寫法Oracle儲存過程
- Oracle 儲存過程分頁 + Sqlsugar呼叫Oracle儲存過程SqlSugar
- oracle儲存過程和觸發器Oracle儲存過程觸發器
- 關於Entity Freamwork 儲存過程操作儲存過程
- Mysql 儲存過程的使用MySql儲存過程
- jsp中呼叫儲存過程JS儲存過程
- Sqlserver中的儲存過程SQLServer儲存過程
- 使用儲存過程(PL/SQL)向資料庫中儲存BLOB物件儲存過程SQL資料庫物件
- ibatis呼叫oracle儲存過程(極簡版)BATOracle儲存過程
- 記一次使用Asp.Net Core WebApi 5.0+Dapper+Mysql+Redis+Docker的開發過程ASP.NETWebAPIAPPMySqlRedisDocker
- 使用JPA和Hibernate呼叫儲存過程的最佳方法 - Vlad Mihalcea儲存過程
- ASP.NET Core 效能優化最佳實踐ASP.NET優化
- Laravel 中使用 MySQL 儲存過程LaravelMySql儲存過程
- vertica 如何實現儲存過程?儲存過程
- Springboot呼叫Oracle儲存過程的幾種方式Spring BootOracle儲存過程
- Oracle 編譯儲存過程卡死解決方法Oracle編譯儲存過程
- 實時流處理與分散式儲存過程中對檔案的操作分散式儲存過程
- oracle使用儲存過程將表資料以excel格式匯出Oracle儲存過程Excel
- SQL 儲存過程裡呼叫另一個儲存過程SQL儲存過程
- 輕量ORM-SqlRepoEx (五) 儲存過程操作ORMSQL儲存過程
- 23. 使用MySQL之使用儲存過程MySql儲存過程