Oracle Database¶
This guide provides step-by-step instructions for setting up Entity Framework Core with Oracle Database and importing your database schema into your .NET application using the SAIF platform templates.
๐ Useful Resources¶
- Entity Framework Core Documentation
- Oracle EF Core Provider
- EF Core Database First
- EF Core CLI Tools
- SAIF Platform Entity Framework Package
๐ Prerequisites¶
Before you begin, ensure you have:
- โ A System API project created with SAIF platform templates (with Oracle database selected)
- โ SAIF platform templates installed
- โ .NET 10.0 SDK installed
- โ Access to an Oracle Database instance
- โ Oracle database connection credentials
โก Oracle Database Setup¶
When you create a System API using the SAIF platform templates, you can select Oracle as your database during the initial project creation. This will automatically set up the necessary projects and configuration files.
๐ฆ What's Included¶
Your System API project with Oracle will include:
๐ Projects¶
- Data Project: Contains Entity Framework context and data models
- Data.Seed Project: Contains data seeding functionality (if applicable)
๐ง Additional Files¶
- OracleDatabaseResourceBuilder.g.cs: Extension method for Aspire integration with Oracle Database
๐ Adding Oracle to an Existing Project¶
If you created your System API without Oracle and need to add it later, you can use the feature template:
dotnet new saif-feature-database-oracle --name <your-app-name> --force --project_id <your-project-id>
Parameters:
--name: Replace<your-app-name>with your application name (e.g., "myapp")--project_id: Replace<your-project-id>with your project identifier (e.g., "it-api-sys-myapp")--force: Overwrites existing files if they exist
๐ Setting Up Kerberos Authentication¶
For local development with Oracle databases, you need to configure Kerberos authentication to securely connect to the database using your Active Directory credentials.
๐ Requirements¶
- โ Oracle Client installed on your machine (version 19.3 or later)
- โ Active Directory account with database access
- โ Windows environment
๐ Step 1: Locate Your Oracle Installation¶
First, find the Oracle client installation path:
- Open PowerShell or Command Prompt
- Run the following command:
- Look for the first Oracle reference in the PATH, for example:
This is your ORACLE_HOME path. The base directory (e.g., C:\Oracle\product\19.3.0\client_64) is what you'll need for configuration.
๐ Step 2: Create Kerberos Configuration Directory¶
Navigate to your Oracle installation's network configuration folder and create a Kerberos directory:
# Example path - adjust based on your ORACLE_HOME
cd C:\Oracle\product\19.3.0\client_64\network\admin
mkdir kerberos
The full path should be: C:\Oracle\product\19.3.0\client_64\network\admin\kerberos
๐ Step 3: Create krb5.conf File¶
Create a file named krb5.conf in the kerberos directory with the following content:
File location: C:\Oracle\product\19.3.0\client_64\network\admin\kerberos\krb5.conf
[libdefaults]
default_realm = CORP.SAIF.COM
[realms]
CORP.SAIF.COM = {
kdc = CORP.SAIF.COM:88
}
[domain_realm]
.CORP.SAIF.COM = CORP.SAIF.COM
CORP.SAIF.COM = CORP.SAIF.COM
.corp.saif.com = CORP.SAIF.COM
corp.saif.com = CORP.SAIF.COM
Configuration explanation:
default_realm: The default Kerberos realm (SAIF corporate domain)kdc: The Kerberos Key Distribution Center server and portdomain_realm: Maps domain names to Kerberos realms
โ๏ธ Step 4: Update sqlnet.ora File¶
Locate and update the sqlnet.ora file in your Oracle network\admin directory:
File location: C:\Oracle\product\19.3.0\client_64\network\admin\sqlnet.ora
Add or update the following configuration:
SQLNET.KERBEROS5_CC_NAME=MSLSA:
SQLNET.KERBEROS5_CONF=C:\Oracle\product\19.3.0\client_64\network\admin\kerberos\krb5.conf
SQLNET.KERBEROS5_CONF_MIT=TRUE
SQLNET.AUTHENTICATION_SERVICES=(BEQ,KERBEROS5)
SQLNET.FALLBACK_AUTHENTICATION=TRUE
SQLNET.AUTHENTICATION_SERVICES= (NTS)
NAMES.DIRECTORY_PATH= (TNSNAMES, EZCONNECT)
Important:
- Replace
C:\Oracle\product\19.3.0\client_64with your actual ORACLE_HOME path - If the file already exists, update the
SQLNET.KERBEROS5_CONFline and add the last two lines if they don't exist
Configuration explanation:
SQLNET.KERBEROS5_CC_NAME: Points to the Microsoft Kerberos credential cacheSQLNET.KERBEROS5_CONF: Path to your krb5.conf fileSQLNET.KERBEROS5_CONF_MIT: Enables MIT Kerberos compatibilitySQLNET.AUTHENTICATION_SERVICES: Specifies authentication methods (Kerberos5 and NTS)SQLNET.FALLBACK_AUTHENTICATION: Allows fallback to alternative authentication if Kerberos failsNAMES.DIRECTORY_PATH: Specifies name resolution methods
๐ซ Step 5: Obtain Kerberos Ticket¶
Before connecting to the database, you need to obtain a Kerberos ticket using your Active Directory credentials:
Example:
You'll be prompted to enter your Active Directory password. After successful authentication, you'll receive a Kerberos ticket.
๐ Step 6: Connect to Oracle Database¶
Once you have a valid Kerberos ticket, you can connect to the Oracle database without specifying credentials:
Example:
The @ symbol followed by the TNS alias connects using Kerberos authentication without requiring username/password.
โ Verify Configuration¶
To verify your Kerberos configuration is working:
- Check your Kerberos ticket:
This shows your current Kerberos tickets and their expiration times.
- Test database connection:
If successful, you should connect without entering credentials.
๐ Ticket Management¶
Kerberos tickets expire after a certain period (typically 10 hours). When your ticket expires:
- Renew your ticket:
- Check ticket status:
- Destroy tickets (logout):
๐ง Troubleshooting Kerberos¶
Error: "kerberos5_conf_mit=false only supported with -old option."¶
This error typically indicates a mismatch between your TNS_ADMIN environment variable and your Oracle installation path.
Solution:
- Check your TNS_ADMIN environment variable:
- Verify it matches your Oracle network\admin path:
The output should match your Oracle installation path, for example:
- If it doesn't match, update the TNS_ADMIN environment variable:
Option A: Set temporarily for current session:
Option B: Set permanently (System Environment Variables):
- Right-click This PC โ Properties โ Advanced system settings
- Click Environment Variables
- Under System variables or User variables, find
TNS_ADMIN - Click Edit (or New if it doesn't exist)
- Set the value to your Oracle network\admin path
-
Click OK and restart your terminal/IDE
-
Verify the change:
- Try connecting again:
๐ Additional Resources¶
For more detailed information about Oracle Kerberos authentication, refer to the Oracle Database Security Documentation.
๐ก Tips¶
- โ
Run
okinitat the start of your development session - โ Set up a reminder to renew tickets before they expire
- โ
Keep your
sqlnet.oraandkrb5.conffiles backed up - โ Ensure your Active Directory account has appropriate database access permissions
- โ Verify TNS_ADMIN environment variable matches your Oracle installation path
โ๏ธ Configuration¶
๐ Local Development¶
For local development, the Oracle database setup uses a local Oracle database and Aspire service discovery for connection string management. Connection strings are automatically configured through Aspire, so you don't need to manually add them to configuration files.
๐ฅ Importing Schema from Oracle Database¶
Entity Framework Core provides powerful tools to scaffold your existing Oracle database schema into C# classes. This is known as the "Database First" approach.
๐ฆ Step 1: Add Required NuGet Packages¶
Before scaffolding, add the required packages to your Data project:
- Right-click on your Data project in Visual Studio
- Select Manage NuGet Packages
- Search for and install:
- Oracle.ManagedDataAccess.Kerberos
- Microsoft.EntityFrameworkCore.Design
Or use the Package Manager Console:
Install-Package Oracle.ManagedDataAccess.Kerberos
Install-Package Microsoft.EntityFrameworkCore.Design
Note: Both packages are only needed for scaffolding and can be removed afterward.
๐ฅ๏ธ Step 2: Open Solution in Visual Studio¶
- Navigate to the root directory of your repository
- Open the solution file (
.sln) in Visual Studio - Locate your Data project (e.g.,
[project-id].Data)
๐ป Step 3: Open Developer PowerShell¶
Open the Developer PowerShell terminal in the correct directory:
- In Solution Explorer, right-click on your Data project
- Select Open in Terminal
This will open a Developer PowerShell window already positioned in your Data project folder.
โ๏ธ Step 4: Set PowerShell Variables¶
Set up the variables for the scaffolding command:
$schema = "[schema_for_the_tables_you_want_to_import]"
$applicationName = "[applicationName]"
$dbcontext = $applicationName + "Context.Custom"
$namespace = $applicationName + ".Data"
Example:
$schema = "PREMIUMAUDIT"
$applicationName = "PremiumAudit"
$dbcontext = $applicationName + "Context.Custom" # Results in "PremiumAuditContext.Custom"
$namespace = $applicationName + ".Data" # Results in "PremiumAudit.Data"
๐ Step 5: Run Scaffold Command¶
Option A: Scaffold by Schema (Recommended)¶
Use this approach to import all tables from a specific schema:
dotnet ef dbcontext scaffold "User Id=/;Data Source=ORADEV08.CORP.SAIF.COM:1521/enttst1" Oracle.EntityFrameworkCore --context $dbcontext --namespace $namespace --no-onconfiguring --schema $schema
What this does:
User Id=/: Uses Kerberos authentication (no username/password needed)Data Source=ORADEV08.CORP.SAIF.COM:1521/enttst1: Connection to the Oracle database- You can use any Oracle database you have read access to (development, test, or production)
- Replace with your target database server and service name
- Example alternatives:
ORAPRD01.CORP.SAIF.COM:1521/entprd1,entdev1, etc. --context $dbcontext: Names your DbContext class (e.g.,PremiumAuditContext)--namespace $namespace: Sets the namespace (e.g.,PremiumAudit.Data)--no-onconfiguring: Excludes the OnConfiguring method (connection strings managed by Aspire)--schema $schema: Imports all tables from the specified schema
Option B: Scaffold Specific Tables ๐ฏ¶
If your schema contains more tables than you need, specify individual tables:
dotnet ef dbcontext scaffold "User Id=/;Data Source=ORADEV08.CORP.SAIF.COM:1521/enttst1" Oracle.EntityFrameworkCore --context $dbcontext --namespace $namespace --no-onconfiguring --table [schema].[table1] --table [schema].[table2]
๐ก Example importing location_code table:
dotnet ef dbcontext scaffold "User Id=/;Data Source=ORADEV08.CORP.SAIF.COM:1521/enttst1" Oracle.EntityFrameworkCore --context $dbcontext --namespace $namespace --no-onconfiguring --table WCIS_DBA.LOCATION_CODE
๐ What this does:
- ๐ฅ Imports only the
LOCATION_CODEtable from theWCIS_DBAschema - ๐ Creates entity class:
LocationCode.cs - ๐ Generates a DbContext with
DbSet<LocationCode>property - ๐ซ Excludes all other tables in the schema
๐ก Pro Tip: To import multiple tables, simply add more --table parameters. Use --force to overwrite existing files when re-scaffolding:
dotnet ef dbcontext scaffold "User Id=/;Data Source=ORADEV08.CORP.SAIF.COM:1521/enttst1" Oracle.EntityFrameworkCore --context $dbcontext --namespace $namespace --no-onconfiguring --table WCIS_DBA.LOCATION_CODE --force
โจ When to use this approach:
- โ Your schema has many tables but you only need a subset
- โ You want to minimize the number of generated entity classes
- โ You want to avoid importing system or audit tables
- โ You know exactly which tables your application needs
๐ง Command Parameters Explained¶
| Parameter | Description |
|---|---|
User Id=/ |
Uses Kerberos authentication instead of username/password |
Data Source |
Oracle server connection string (server:port/service_name) |
| Provider | Oracle.EntityFrameworkCore - The Oracle EF Core provider |
--context |
Name of the DbContext class (e.g., PremiumAuditContext) |
--namespace |
Namespace for generated classes (e.g., PremiumAudit.Data) |
--no-onconfiguring |
Excludes OnConfiguring method (connection managed externally by Aspire) |
--schema |
Schema to import (imports all tables from this schema) |
--table |
Specific table to import (format: [schema].[table], can be repeated for multiple tables) |
๐ Choosing Between Schema and Table Import¶
Use --schema when:
- โ You need all or most tables from a schema
- โ The schema is dedicated to your application
- โ You want to ensure all related tables are imported
Use --table when:
- โ You only need specific tables from a larger schema
- โ The schema contains many tables you don't need
- โ You want fine-grained control over what gets imported
- โ You want to minimize the size of your data project
๐งน Step 6: Remove Scaffolding Packages (Optional)¶
After successfully scaffolding your database schema, you can remove the packages that were only needed for scaffolding:
- Right-click on your Data project in Visual Studio
- Select Manage NuGet Packages
- Find and uninstall:
- Oracle.ManagedDataAccess.Kerberos
- Microsoft.EntityFrameworkCore.Design
Or use the Package Manager Console:
Uninstall-Package Oracle.ManagedDataAccess.Kerberos
Uninstall-Package Microsoft.EntityFrameworkCore.Design
Note: These packages are only required during the scaffolding process. Your application uses the standard Oracle Entity Framework provider for runtime database connections.
โ ๏ธ Step 7: Update Decimal Types to Long¶
Important: Oracle's EF Core provider generates decimal types for Oracle NUMBER columns, but you'll typically want to use long (Int64) for better performance and compatibility.
After scaffolding, you'll need to:
- Review generated entity classes and identify
decimalproperties that should belong - Update the data types from
decimaltolongfor: - โ Primary keys (IDs)
- โ Foreign keys
- โ Integer values stored in Oracle NUMBER columns
- Keep
decimalfor actual decimal/currency values that need precision
Why make this change?
- ๐ Performance:
longis more efficient thandecimalfor integer operations - ๐ฏ Type safety: Prevents accidental decimal arithmetic on integer IDs
- ๐ API compatibility: Most APIs expect integer IDs, not decimals
- ๐พ Memory efficiency:
longuses less memory thandecimal
Note: You'll need to make these changes after each scaffold/re-scaffold operation.
๐ Project Structure After Scaffolding¶
After running the scaffold command, your Data project will contain:
- [ApplicationName]Context.Custom.cs: The generated DbContext file with all entity DbSets and configurations
- Entity model files: One C# class file for each table you imported (e.g.,
LocationCode.cs,Policy.cs)
These generated files work together with the base context file included in the SAIF template to provide your complete data access layer.
๐ Updating Your Data Model¶
When your Oracle database schema changes, you'll need to re-scaffold to update your entity models.
๐ Re-scaffolding Process¶
- Make sure you have the latest database schema in your Oracle database
- Run the scaffold command again with the
--forceflag to overwrite existing files - Review the changes to ensure they match your expectations
- Test your application to ensure everything works correctly
โ ๏ธ Important Notes on Re-scaffolding¶
- Custom code will be overwritten: Any manual changes you made to generated entity classes will be lost
- Use partial classes: To add custom logic to entities, use partial classes in separate files
- Source control: Always commit your changes before re-scaffolding so you can review differences
๐ฏ Extending Generated Models with Partial Classes¶
Create partial class files to add custom logic without modifying generated code:
// Employee.Custom.cs (create this file separately)
namespace YourApp.Data.Models
{
public partial class Employee
{
// Add custom properties
[NotMapped]
public string FullName => $"{FirstName} {LastName}";
// Add custom methods
public bool IsActive()
{
// Your custom logic
return HireDate.HasValue;
}
}
}
โจ Best Practices¶
๐ฏ Database First Workflow¶
- Design your schema in Oracle using SQL scripts or database tools
- Apply schema changes to your Oracle database
- Scaffold the updated schema using EF Core tools
- Review and test the generated models
- Commit changes to source control
๐ Security Best Practices¶
- โ Never commit connection strings with credentials to source control
- โ Use Azure Key Vault for storing production connection strings
- โ Use separate credentials for different environments
- โ Implement least privilege access - grant only necessary database permissions
๐ Performance Best Practices¶
- โ Use AsNoTracking() for read-only queries to improve performance
- โ Use projection (Select) to retrieve only needed columns
- โ Implement proper indexing in your Oracle database
- โ Use connection pooling (enabled by default with Oracle provider)
- โ Consider pagination for large result sets
๐งช Code Organization¶
- โ
Keep generated models in a separate folder (e.g.,
Models/) - โ Use partial classes for custom logic
- โ Separate concerns - keep business logic out of entity models
โ๏ธ Azure Deployment Configuration¶
For deployment to Azure, you need to configure Oracle database settings in two places:
1. Settings Configuration (infra/api/settings.yml)¶
Update the settings.yml file with your Oracle database configuration:
Configuration values:
oracle-username: The username for connecting to your Oracle database (e.g.,username,SYSTEM)oracle-instance-type: The Oracle instance type you selected during project creation (e.g.,ENT,POL,CLM)
2. Password Configuration (Azure DevOps Library)¶
Oracle database passwords are stored securely in Azure DevOps Library as variables. Follow these steps:
-
Navigate to Azure DevOps:
-
Go to Pipelines โ Library in the Team Project where your application repository is stored
-
Create or update a variable group:
-
Create a variable group with the naming pattern:
<api>-<project_id>-<environment>(e.g.,au-api-sys-premiumaudit) -
Add a description like "Database credentials to Oracle ENTDB"
-
Add password variables for each environment:
- Variable name pattern:
[ENV]oracle-password(e.g.,[PROD]oracle-password,[TEST]oracle-password) - Click the Lock icon to mask the password value
- Paste your database password in the Value field
Example variable group setup:
| Name | Value |
|---|---|
[PROD]oracle-password |
**** (locked) |
[QA]oracle-password |
**** (locked) |
[TEST]oracle-password |
**** (locked) |
[UAT]oracle-password |
**** (locked) |
๐ Complete Configuration Example¶
Here's a complete example of Oracle configuration in settings.yml:
# infra/api/settings.yml
# Oracle Database Configuration
- name: oracle-username
value: username
- name: oracle-instance-type
value: ENT
# Other application settings...
- name: ApplicationName
value: MyApp
Important Notes:
- โ
The
oracle-instance-typeis typically set during project creation and rarely changes - โ
Only update
oracle-usernameif you need to use a different database user - โ
Never commit passwords to
settings.yml- always use Azure DevOps Library - โ Password variables must be locked/masked in the Azure DevOps Library
For more detailed information on settings and secrets management, refer to the Settings and Secrets Management Guide.
๐ Troubleshooting¶
โ Common Issues and Solutions¶
Issue: "Could not find provider Oracle.EntityFrameworkCore"¶
Solution: Make sure you have the Oracle EF Core provider package installed:
Issue: "Unable to connect to database"¶
Solutions:
- โ Verify your connection string is correct
- โ Check that the Oracle database is running and accessible
- โ Ensure firewall rules allow connection to Oracle port (usually 1521)
- โ Verify your username and password are correct
- โ Check that the service name or SID is correct
Issue: "Tables not being scaffolded"¶
Solutions:
- โ Ensure your database user has SELECT permissions on the tables
- โ Check if tables exist in the correct schema
- โ
Use
--schemaparameter if tables are in a non-default schema - โ
Verify table names are spelled correctly if using
--tableparameter
Issue: "Generated models have incorrect data types"¶
Solutions:
- โ Update to the latest version of Oracle.EntityFrameworkCore
- โ Review Oracle to .NET type mappings
- โ Manually adjust types after scaffolding (in partial classes)
Issue: "Re-scaffolding overwrites my custom code"¶
Solution: Always use partial classes for custom logic:
// Keep this file - it gets regenerated
// Employee.cs (generated)
// Create this file for custom code - never gets overwritten
// Employee.Custom.cs (your custom partial class)
public partial class Employee
{
// Your custom code here
}
Issue: "Aspire unable to pull Oracle container image"¶
Problem: When using Aspire, the Oracle container may fail to start because the Docker image cannot be pulled automatically.
Solution: Manually pull the Oracle Docker image:
- Check the Oracle container source in your Aspire project to identify the image name
- Open Command Prompt or PowerShell
- Manually pull the image:
Example:
# Oracle Free Database container image
docker pull container-registry.oracle.com/database/free:23.8.0.0
Additional troubleshooting steps:
- โ Ensure Docker Desktop is running
- โ Check your internet connection
- โ Verify you have sufficient disk space for the Oracle image
- โ If using Oracle Enterprise images, ensure you're authenticated with Oracle Container Registry
- โ
Check Docker logs:
docker logs <container_name>
๐ Getting Help¶
If you encounter issues not covered here:
- Check the Entity Framework Core Documentation
- Review Oracle EF Core Provider Documentation
- Consult the SAIF Platform team
- Check existing issues in your project's repository
๐ Next Steps¶
After setting up Entity Framework with Oracle:
- ๐ Read about Settings and Secrets Management
- ๐ Learn about Blue-Green Deployments
- ๐งช Implement unit tests for your data access layer
- ๐ Set up monitoring and logging with Application Insights
- ๐ Configure CI/CD pipelines for database schema management
Happy Coding! ๐