This article will focus on how to create Asp.Net Core Web API to get data from Oracle database using Dapper ORM. First thing, here we are not using SQL, because of so many articles available on Internet where mostly SQL server is using for demonstration. So, we think, let write one article where we will use Oracle as a database. To reduce the complexity of database access logic we are using Dapper ORM. So, let's move to practical demonstration.
Create Asp.Net Core Web API Project
To create a new project in Asp.Net Core Web API. Just open Visual Studio 2017 version 15.3 and we have to follow below steps.
- Go to File menu and click to New and then choose Project.
- From the New Project window, first, you have to choose .Net Framework 4.6 or above version and then from the left panel, choose Visual C# and then .Net Core.
- From the right panel, choose “Asp.Net Core Web Application” and provide the save location where you want to save project and click OK.
- From the next windows, which will provide you different kinds of the template, you have to choose Web API.
Now click to OK. It will take few minutes to configure Asp.Net Core Web API project.
Setup Oracle Table and Stored Procedures
To create database and tables for this demonstration, we are using Oracle Developer Tools. It is very lightweight and flexible which help us to work with database smoothly.
As per Oracle
Create a database name call it "TEST_DB" and inside that create a table name as "EMPLOYEE". You can use the following syntax to create the table inside "TEST_DB" database.
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" ;
Need to add some dummy records inside the tables, so that we can directly get the data from PostMan. So, we are adding four records here as follows.
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');
Now its time to create one SP which will bring the list of employees records. Here we are using Cursor for returning list of data as an output parameter.
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;
Now going to create one SP which will get the individual record for an employee based on their employee id.
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;
Install Dapper ORM
Open "Package Manager Console" from the "Nuget Package Manager" of Tools menu and type following command and press enter to install dapper and its dependencies if have.
Install-Package Dapper -Version 1.50.5
After installation, you can check with references section of the project. One reference as "Dapper" has added inside that.
Install Oracle Manage Data Access for Core
As we are using Asp.Net Core Web API application with Oracle and need to access Oracle database from the Core application. To use Oracle database with .Net Core application, we have Oracle library which will help us to manage logic of database access. So, we have to install following package that is beta version.
Add Oracle Connection
Now we have everything ready related to the database like the database, tables, and SPs etc. To access the database from Web API, we have to create connection string as usual inside the "appsettings.json" file.
{
"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;"
}
}
Create Repositories
To keep the separation of concern in mind, we are using Repository here. Create a new folder as "Repositories" inside the Web API project and create an interface as "IEmployeeRepository" and a class as "EmployeeRepository" which will implement to IEmployeeRepository.
namespace Core2API.Repositories
{
public interface IEmployeeRepository
{
object GetEmployeeList();
object GetEmployeeDetails(int empId);
}
}
Following is the EmployeeRepository class which is implementing IEmployeeRepository. To access configuration, we are injecting IConfiguration in the constructor. So, we have configuration object is ready to use. Apart from that we have GetConnection() method which will get the connection string from the appsettings.json and provide it to OracleConnection to create a connection and finally return connection. As we have implemented "IEmployeeRepository" which have two methods as GetEmployeeDetails and 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;
}
To use Oracle datatypes with .Net Core, we are using OracleDyamicParameters class which will provide the list of function to manage Oracle parameters behaviors.
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());
}
}
}
}
Configure Dependencies in Startup.cs
To access the dependencies on the controller or repository classes, we have to configure or we can say register our dependency classes with interfaces inside the ConfigureServices method of Startup class.
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();
}
}
}
Add EmployeeController
Now its time to finally create API call in EmployeeControler. First, we have added IEmployeeRepository inside the constructor to use dependencies. Secondly, we have to create API call with Route attribute for both methods.
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);
}
}
}
Now we have ready everything like repository is ready, connection with Oracle database is ready and finally, API call is also ready inside the controller. So, its time to run the API and see the result in PostMan. Just press F5 to run the Web API and open PostMan to test the result.
To test in PostMan, first, choose "Get" as a method and provide the URL to get the list of employee records and click to SEND button which will make a request to our API and get the list of employees which we have added at the beginning while creating the database scripts.
To get the single employee record, just pass the following URL as you can see in the image. You can see here, we want to see the record for employee id 103. Once you send the request, you can see the output something like as below.
Conclusion
So, today we have learned how to create Asp.Net Core Web API project and use Dapper with Oracle database.
I hope this post will help you. Please put your feedback using comment which helps me to improve myself for next post. If you have any doubts please ask your doubts or query in the comment section and If you like this post, please share it with your friends.
Posted Comments :
Amanda Chua Posted : 6 Years Ago
Great information. Since last week, I am gathering details about asp experience. There are some amazing details on your blog which I didn’t know. Thanks.
Lee Ying Posted : 6 Years Ago
Very impressive information Mukesh and I am gonna implement on https://www.codigeeks.com/web-app-development/
kiran Posted : 6 Years Ago
Error find in the connection - > Oracle.ManagedDataAccess.Client.OracleException: 'ORA-12154: TNS:could not resolve the connect identifier specified'
Omer Posted : 6 Years Ago
Hi, I have implemented it on vs 2017 and it works fine Now I want t implement it on vs 2015, I have done everything but these two functions are not available in vs 2015 Do you know any alternative of these two: UseHsts() & UseHttpsRedirection As they are not available in core 1.0 Thanks.
Shiv kumar Posted : 5 Years Ago
Nice Information deliver by You about asp .net core with oracle database dapper.
Kayser Posted : 5 Years Ago
Getting Error while opening the connection - > Oracle.ManagedDataAccess.Client.OracleException: 'ORA-12154: TNS:could not resolve the connect identifier specified'
SHILPA Posted : 5 Years Ago
Getting error while opening the connection 'ORA-12154: TNS:could not resolve the connect identifier specified'
Chuck Posted : 4 Years Ago
To above ORA-12154 issues. Should be "EmployeeConnection": "data source=hostname:1531/servicename;password=**********;user id=mukesh;Incr Pool Size=5;Decr Pool Size=2;"
sreedhar Posted : 4 Years Ago
Nice article how to access multiple ref cursor
Clark Posted : 3 Years Ago
Amazing article, hope to see more tutorial from you! Thank you very much!
ozay bakirhan Posted : 3 Years Ago
Hi Kumar? Based on your code set up to execute a store procedure, how do i return an output parameter which added earlier with dyParam? for example; var dyParam = new OracleDynamicParameters(); dyParam .Add("FIRSTNAME", OracleDbType.Varchar2, ParameterDirection.Input, "MUKEHS"); dyParam .Add("LASTNAME", OracleDbType.Varchar2, ParameterDirection.Input, "KUMAR"); dyParam .Add("ID", OracleDbType.Int32, ParameterDirection.Output, null); . . var query = "INSERT_GETEMPLOYEES"; result = SqlMapper.Execute(conn, query, param: dyParam, commandType: CommandType.StoredProcedure); int id = ??????
kumuduni Posted : Last Year
Thank you very much Mukesh..Simple and easy guide.. Done the API easily... Hope to see more posts from you....Good luck.
Dan Posted : 6 Years Ago
Hi Mukesh, one question: If I wanted the "GetEmployeeDetails" method return a JSON and not a JSON array, what should I do?. I tried to use the "FirstOrDefault()" function in the repository but it gives me error. Thank you.