Migrating Oracle To Postgres Data Access Code
GitHubOfficialFirst committed by PrimedPaulDistributed by GitHub
- Skill
- Workflow
- Software development
- MIT
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a systematic, seven-step procedure for refactoring C# data access code from Oracle.ManagedDataAccess to Npgsql. It focuses on replacing NuGet packages, updating connection strings, mapping ADO.NET types, and translating Oracle-specific SQL constructs to PostgreSQL-compatible syntax. The workflow is designed to be executed on a dedicated copy of the project, ensuring the original remains untouched while maintaining strict adherence to existing project configurations and versions.
What it does
- Replaces Oracle-specific NuGet packages with Npgsql equivalents.
- Updates ADO.NET type references and parameter mappings for PostgreSQL compatibility.
- Provides a mapping table for translating Oracle SQL functions and syntax to PostgreSQL.
- Guides the migration of stored procedure invocations and ref cursor handling.
- Offers specific instructions for updating EF Core provider configurations.
- Includes a verification step to ensure all Oracle-specific dependencies are removed.
When to use it
- When migrating the application code layer of a .NET project from an Oracle database to PostgreSQL.
- When you need a repeatable, checklist-driven process to refactor data access layers.
- When you are working on a dedicated project copy and need to ensure no Oracle-specific code remains.
Advantages
- Reduces manual error by providing a clear, step-by-step migration path.
- Ensures consistency across the codebase by standardizing type and syntax replacements.
- Minimizes risk by mandating work on a separate project copy.
- Provides clear guidance on handling complex Oracle-specific features like RefCursors and hierarchical queries.
Usage examples
- “How do I start migrating my C# data access layer from Oracle to PostgreSQL?”
- The agent will guide you through the initial setup, including creating a project copy, initializing the migration checklist, and performing the first step of replacing NuGet packages.
- “What should I replace OracleDbType.Varchar2 with in my Npgsql code?”
- The agent will advise using NpgsqlDbType.Varchar or omitting the explicit type setting, as Npgsql can often infer the type from the value.
- “How do I handle Oracle's ROWNUM in my PostgreSQL migration?”
- The agent will instruct you to replace ROWNUM constructs with the PostgreSQL LIMIT clause.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/github/migrating-oracle-to-postgres-data-access-code/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip migrating-oracle-to-postgres-data-access-code.zip -d .agents/skills
Documentation by PrimedPaul
Migrating .NET Data Access Code from Oracle to PostgreSQL
Migrate the C# data access layer of a single .Postgres-copy project from Oracle (Oracle.ManagedDataAccess) to PostgreSQL (Npgsql). Work item by item through Reports/{ProjectName}/MigrationChecklist.md.
Prerequisites
The
.Postgresproject copy exists (created in Phase 5 setup).Reports/{ProjectName}/MigrationChecklist.mdexists and is the source of truth for what to change.Reports/{ProjectName}/OracleRiskAnalysis.mdexists for cross-referencing behavioral differences.
Workflow
Progress:
- [ ] Step 1: Replace NuGet packages
- [ ] Step 2: Update connection string configuration
- [ ] Step 3: Rewrite ADO.NET type references
- [ ] Step 4: Fix DbType mappings
- [ ] Step 5: Migrate stored procedure invocation
- [ ] Step 6: Address Oracle-specific SQL and syntax
- [ ] Step 7: Build and verifyStep 1: Replace NuGet packages
In the .csproj of the .Postgres project:
Remove:
Oracle.ManagedDataAccess.Core,Oracle.EntityFrameworkCore(and any otherOracle.*packages)Add:
Npgsql(for ADO.NET) and/orNpgsql.EntityFrameworkCore.PostgreSQL(for EF Core)Keep version pinning consistent with the target .NET version; do not introduce newer package versions than what the solution already uses for similar packages.
If
System.Dataabstractions (IDbConnection,IDbCommand) are used project-wide, the surface-level code may need fewer changes — identify them first.
Step 2: Update connection string configuration
Locate the Oracle connection string in
appsettings.json,appsettings.{env}.json,web.config,app.config, or environment variable configuration.Replace with a Npgsql-compatible connection string:
Host=localhost;Port=5432;Database=mydb;Username=myuser;Password=mypasswordDo not hardcode credentials — use the same configuration mechanism already in use (e.g., environment variables, secrets manager,
IConfiguration).Update any named connection string keys only if they were Oracle-specific (e.g.,
OracleConnection). Prefer keeping the same key name to minimize application config changes.
Step 3: Rewrite ADO.NET type references
Replace Oracle-specific ADO.NET types with Npgsql equivalents:
| Oracle type | Npgsql replacement |
|---|---|
OracleConnection | NpgsqlConnection |
OracleCommand | NpgsqlCommand |
OracleDataReader | NpgsqlDataReader |
OracleDataAdapter | NpgsqlDataAdapter |
OracleParameter | NpgsqlParameter |
OracleTransaction | NpgsqlTransaction |
OracleException | NpgsqlException |
OracleDbType | NpgsqlDbType (from NpgsqlTypes namespace) |
Update using directives accordingly (using Oracle.ManagedDataAccess.Client → using Npgsql).
If the codebase uses IDbConnection/IDbCommand abstractions registered via DI, update only the DI registration and connection string — the consuming code may not need changes.
Step 4: Fix DbType and NpgsqlDbType mappings
Oracle parameter types do not map 1:1 to Npgsql. Review every OracleParameter (now NpgsqlParameter) that sets an explicit type:
| Oracle type | Notes |
|---|---|
OracleDbType.Varchar2 | Use NpgsqlDbType.Varchar or omit (Npgsql infers from value) |
OracleDbType.Clob | Use NpgsqlDbType.Text |
OracleDbType.Number | Use NpgsqlDbType.Numeric or NpgsqlDbType.Integer depending on precision |
OracleDbType.Date | Use NpgsqlDbType.Date (date only) or NpgsqlDbType.Timestamp (if time component used) |
OracleDbType.TimeStamp | Use NpgsqlDbType.Timestamp |
OracleDbType.RefCursor | Use NpgsqlDbType.Refcursor — see Step 5 |
OracleDbType.Char | Use NpgsqlDbType.Char |
For parameters where Oracle inferred the type from the value, Npgsql also infers — explicit type setting is often unnecessary and can be removed.
Step 5: Migrate stored procedure invocation
Oracle and PostgreSQL stored procedure invocation differ significantly:
Command type: Retain
CommandType.StoredProcedurefor function calls. For procedures that useOUTparameters, PostgreSQL requiresCommandType.TextwithCALL proc_name(...)syntax in some versions of Npgsql — verify against the target Npgsql version.RefCursor handling: Oracle returns ref cursors as output parameters; PostgreSQL returns them differently:
For
RETURNS TABLE/RETURNS SETOF, useExecuteReader()directly — no cursor parameter needed.For
RETURNS refcursor, call within a transaction, read the cursor name from the output parameter, then issueFETCH ALL IN "<cursor_name>".Remove any Oracle-specific cursor-wrapping code (e.g.,
OracleRefCursor).
OUT parameters: PostgreSQL stored procedures use
INOUTor function return values. Verify parameter direction matches the migrated procedure signature.Sequence
NEXTVAL: ReplaceSELECT {SEQUENCE}.NEXTVAL FROM DUALwithSELECT nextval('{sequence_name}').Named parameters: Npgsql uses
@param_name; Oracle used:param_name. Update all parameter name prefixes.
Step 6: Address Oracle-specific SQL and C# patterns
Review inline SQL strings and query builders for Oracle-specific constructs and replace:
| Oracle construct | PostgreSQL replacement |
|---|---|
ROWNUM <= n | LIMIT n |
ROWNUM = 1 | LIMIT 1 |
NVL(x, y) | COALESCE(x, y) |
DECODE(expr, v1, r1, ...) | CASE WHEN expr = v1 THEN r1 ... END |
SYSDATE / SYSTIMESTAMP | NOW() or CURRENT_TIMESTAMP |
TO_CHAR(date, fmt) | TO_CHAR(date, fmt) (mostly compatible; verify format strings) |
TO_DATE(str, fmt) | TO_DATE(str, fmt) (verify format strings) |
TO_NUMBER(str) | CAST(str AS NUMERIC) or str::NUMERIC |
| ` | |
DUAL table | Remove FROM DUAL; PostgreSQL evaluates SELECT expr without a table |
CONNECT BY hierarchy | Rewrite using recursive CTEs (WITH RECURSIVE) |
MERGE INTO | Rewrite as INSERT ... ON CONFLICT DO UPDATE |
Empty string '' as NULL | Oracle treats '' as NULL; PostgreSQL does not — check comparisons and IS NULL guards |
VARCHAR2 | VARCHAR or TEXT |
Step 7: Build and verify
After addressing all checklist items:
Run
dotnet buildon the.Postgresproject. Fix any remaining compilation errors.Verify no Oracle-specific namespaces remain: search for
Oracle.ManagedDataAccess,OracleConnection,OracleCommand,:parampatterns.Mark completed items in
Reports/{ProjectName}/MigrationChecklist.md.
EF Core projects
If the project uses Oracle.EntityFrameworkCore:
Replace the provider registration in
DbContextconfiguration:.UseOracle(...)→.UseNpgsql(...)Replace
OracleDbContextOptionsBuilderreferences.Review
OnModelCreatingfor Oracle-specific configurations (e.g.,HasColumnType("NUMBER")→HasColumnType("numeric")).Sequence configuration:
modelBuilder.HasSequence<int>("seq_name").StartsAt(1).IncrementsBy(1)syntax is compatible; verify column defaults referencing sequences.Do not run EF Core migrations — schema is managed externally via DDL scripts (Phase 4).
Key Constraints
Work only within the
.Postgrescopy — never modify the original Oracle-targeting project.Keep to existing .NET and C# versions; do not introduce newer language or runtime features.
Preserve comments and application logic; change only what is necessary for PostgreSQL compatibility.
Oracle is the source of truth — behavioral differences must be documented as bug reports, not silently altered.
Files
- ATTRIBUTION.mdAdded by AutoGineer927 B
- LICENSELicence file added by AutoGineer1.0 KiB
- SKILL.md7.9 KiB
Requirements and compatibility
Written for: GitHub Copilot
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- First committed by
PrimedPaul
- Publisher
- GitHub (Official)
- Distributed by
- GitHub
- Source
- github/awesome-copilot · skills/migrating-oracle-to-postgres-data-access-code · commit 797337f
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
- Contributors
- PrimedPaul
AutoGineer is not affiliated with or endorsed by PrimedPaul or GitHub.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download migrating-oracle-to-postgres-data-access-code.zip