In modern web development, keeping your data access logic separate from your business logic is essential for building scalable and maintainable applications. This tutorial demonstrates how to retrieve records from an Oracle Database—specifically handling the common ORA-01861 literal format error—using a robust architecture in ASP.NET Core MVC.
Prerequisites
Visual Studio 2022.
Oracle Managed Data Access (
Oracle.ManagedDataAccess.Core) NuGet package.Dapper NuGet package for lightweight ORM mapping.
Bootstrap 5 for the user interface.
1. The Model (CommissionRecord.cs)
First, we define a class that maps directly to the columns of your Oracle table, such as COMMISSION_INFORMATION_DETAIL. Note that we match the exact database column names (including any specific spellings like COMMISION_DATE).
C#
public class CommissionRecord
{
public string KioskId { get; set; }
public string Product { get; set; }
public int Transactions { get; set; }
public decimal Commission { get; set; }
public DateTime CommisionDate { get; set; }
public int CommissionDetailId { get; set; }
}
2. The Repository Layer (ICommissionRepository.cs)
The repository handles the raw SQL communication. To prevent the ORA-01861: literal does not match format string error, we use parameterized queries instead of hardcoding strings into the SQL.
C#
public interface ICommissionRepository
{
Task<IEnumerable<CommissionRecord>> GetRecordsAsync(string kioskId, DateTime date);
}
public class CommissionRepository : ICommissionRepository
{
private readonly string _connectionString;
public CommissionRepository(IConfiguration config) => _connectionString = config.GetConnectionString("OracleDb");
public async Task<IEnumerable<CommissionRecord>> GetRecordsAsync(string kioskId, DateTime date)
{
using var conn = new OracleConnection(_connectionString);
// TRUNC() ensures we compare only the date part, ignoring the time
const string sql = @"SELECT KIOSK_ID as KioskId, PRODUCT, TRANSACTIONS,
COMMISSION, COMMISION_DATE as CommisionDate,
COMMISSION_DETAIL_ID as CommissionDetailId
FROM COMMISSION_INFORMATION_DETAIL
WHERE KIOSK_ID = :kId
AND TRUNC(COMMISION_DATE) = TRUNC(:dt)";
// Dapper safely maps the C# DateTime to an Oracle Date parameter
return await conn.QueryAsync<CommissionRecord>(sql, new { kId = kioskId, dt = date });
}
}
3. The Service Layer (ICommissionService.cs)
The service layer sits between the controller and the repository. It is responsible for any business logic or validation before querying the database.
C#
Join the conversation! Your thoughts help the community grow.