Using ODP.NET Core + Dapper to Operate Oracle Databases in .NET Core (C#)
Preface Although people have long talked about “de-IOE,” in state-owned enterprises and government, Oracle’s historical baggage is simply too heavy—even a lot of business logic is implemented inside various Oracle stored procedures… Our systems’ main tech stack is Django / Spring / AspNetCore. Needless to say, Java’s support for Oracle is definitely no problem; the key issue is that Django has Oracle version requirements and compatibility isn’t particularly good, and Oracle versions can’t be upgraded at will, so I thought of using .Net
目录5 个章节
Preface
Although people have long talked about “de-IOE,” in state-owned enterprises and government, Oracle’s historical baggage is simply too heavy—even a lot of business logic is implemented inside various Oracle stored procedures…
Our systems’ main tech stack is Django / Spring / AspNetCore. Needless to say, Java’s support for Oracle is definitely no problem; the key issue is that Django has Oracle version requirements and compatibility isn’t particularly good, and Oracle versions can’t be upgraded at will, so I thought of writing a middle layer in .NET Core so that other systems can conveniently use Oracle data and stored procedures…
ODP.NET Core is an ADO.NET driver that provides fast data access from Microsoft .NET Core clients to Oracle Database. It can run on Windows and Linux. ODP.NET consists of a 100% managed-code dynamic-link library, Oracle.ManagedDataAccess.dll, available via NuGet.
This Oracle.ManagedDataAccess.Core is really convenient—no need to install an Oracle client. Compatibility, convenience—anyway, it’s out of the box; just go all in and you’re done.
Simple Usage
First install this Oracle.ManagedDataAccess.Core with NuGet, then you can perform all kinds of operations. Looking at the amount of code, though, it’s still rather tedious. Here’s the code:
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);
}
}
}
This is the code to execute the SQL statement select * from table_name. A bit long…… ugh
Now look at executing a stored procedure…
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);
}
Here I removed the error handling so it looks a bit shorter, but it’s still terribly cumbersome……
So here we’ll use Dapper, this lightweight ORM, to simplify operations.
Using Dapper
Not much to say—first, installing via NuGet is the usual drill; the package name is simply Dapper.
First, ordinary SQL statements like CRUD:
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);
}
You can see that after introducing Dapper, you just use the OracleConnection extension method Query to execute SQL~ The returned result is of type IEnumerable<dynamic>. Of course you can also specify the return type in the generic parameter of the Query method; I don’t specify it here for generality.
Continuing with stored procedures—very simple, pretty much the same as above, just one extra parameter to tell the program what our SQL type is.
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);
}
What if it’s a stored procedure with parameters?
Very simple (code from the official example)~
var user = cnn.Query<User>("spGetUser", new {Id = 1},
commandType: CommandType.StoredProcedure).SingleOrDefault();
ok, very convenient. For more operations, just look at the Dapper docs and you’re done (this is also my first time using Dapper; I used FreeSQL and EFCore before). That’s the end of this article~
Dapper project homepage: https://github.com/StackExchange/Dapper
References
- Using ODP.NET Core in .NET Core to Connect to and Operate an Oracle Database: https://www.cjavapy.com/article/271/
- Component Unboxing: Managed ODP.NET for Linux
Welcome to Discuss
Programming Lab focuses on exploring popular new internet technologies and team agile development practices. Reply with linux, flutter, c#, netcore, android, kotlin, java, python, etc. in the backend of the WeChat official account “程序设计实验室” to get related technical articles and materials. If you have any questions, you can also leave a message in the official account backend~
_EOF_
Using ODP.NET Core + Dapper to Operate Oracle Databases in .NET Core (C#)
- 本文作者:
- 程序设计实验室
- 版权声明:
- 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
相关文章
C#实现生成Markdown文档目录树
前言 之前我写了一篇关于C#处理Markdown文档的文章:C#解析Markdown文档,实现替换图片链接操作 算是第一次尝试使用C#处理Markdown文档,然后最近又把博客网站的前台改了一下,目前文章渲染使用Editor.md组件在前端渲染,但这个插件生成的目录树很丑,我魔改了一下换成bootstrap5-treeview组件,好看多了。详见这篇文章:魔改editormd组件,优化ToC渲染效
2022-10-26 · C# · 约 1 分钟
在.NetCore实现图片缩放与裁剪-基于ImageSharp
前言 ~~(突然发现断更有段时间了~~ 最近在做博客的时候,需要实现一个类似Lorempixel、LoremPicsum这样的随机图片功能,图片有了,还需要一个根据输入的宽度高度获取图片的功能,由于之前处理图片时使用到了ImageSharp库,所以这次我立刻就想到用它。 分析需求 图片库中的图片基本都是我之前收集的壁纸什么的,尺寸参差不齐,有横屏的也有竖屏 然后包装成接口只需要输入宽度和高度,就能
2022-06-17 · C# · 约 1 分钟
C#实现解析Markdown文档并处理图片链接
前言 又是好久没写博客了 其实也不是没写,是最近在「做一个博客」,从2月21日开始,大概一个多星期的时间,疯狂刷进度,边写代码边写了一整系列的博客开发笔记,目前为止已经写了16篇了,然后上3月之后工作有点忙~~加上有点沉迷原神~~,然后进度就暂时慢下来了 事实证明做什么事情一旦停下来就会产生惰性,于是停了这么久,我终于下定决心继续更新! 这次开发的博客用的是C#语言,搭配.netcore技术栈;前
2022-03-19 · C# · 约 1 分钟
C# 扩展方法只会写 this 吗?C# 14 新语法直接把扩展方法玩出了花
.NET 10 的扩展方法语法糖?哦,用 `extension` 块定义扩展,支持属性和方法了,以前不行,现在行,真稀奇。静态扩展成员?太晚了点,给 `DateTime` 添加静态方法,终于能优雅了。升级吧,不然怎么享受这些新玩具?
2026-03-05 · C# · 约 1 分钟
讨论
共 0 条加载评论中…