Oracle.EntityFrameworkCore 9.23.26000

Oracle Logo

Oracle.EntityFrameworkCore 9.23.26000

Release Notes for Oracle Entity Framework Core 9 NuGet Package

October 2025

Oracle Data Provider for .NET (ODP.NET) Entity Framework (EF) Core is a database provider that allows Entity Framework Core to be used with Oracle databases. EF Core is a cross-platform Microsoft object-relational mapper that enables .NET developers to work with relational databases using .NET objects.

This document provides information that supplements the Oracle Data Provider for .NET (ODP.NET) documentation.

New Features

  • None

Bug Fixes / Changes since Oracle.EntityFrameworkCore 9.23.90

  • Bug 38232496 - TO_CHAR() RESULTS IN ORA-01722, WHILE to_char() WORKS AS EXPECTED
  • Upgrade dependency to ODP.NET 23.26.0 or higher

Tips, Limitations, and Known Issues

Code First

  • The HasIndex() Fluent API cannot be invoked on an entity property that will result in a primary key in the Oracle database. Oracle Database does not support index creation for primary keys since an index is implicitly created for all primary keys.
  • The HasFilter() Fluent API is not supported. For example,
modelBuilder.Entity<Blog>()
    .HasIndex(b => b.Url)
    .HasFilter("Url is not null");
  • Data seeding using the UseIdentityColumn is not supported.
  • The UseCollation() Fluent API is not supported.
  • The DateOnly and TimeOnly types are not supported.
  • DatabaseTable.Indexes() is not supported for descending indexes.
  • The following usage is not supported because of a limitation in the provider: -> HasColumnType("float").HasPrecision(38). As a workaround, set the precision value in the HasColumnType() fluent API instead of explicitly using the HasPrecision() fluent API, e.g., HasColumnType("float (38)"). NOTE: Except for 38 as a precision value, other precision values between 1 and 126 can be set using the HasPrecision() Fluent API. This limitation and workaround also apply when annotations are used instead of the above mentioned fluent API's.

Computed Columns

  • Literal values used for computed columns must be encapsulated by two single-quotes. In the example below, the literal string is the comma. It needs to be surrounded by two single-quotes as shown below.
// C# - computed columns code sample
modelBuilder.Entity<Blog>()
    .Property(b => b.BlogOwner)
    .HasComputedColumnSql("\"LastName\" || '','' || \"FirstName\"");

Database Scalar Function Mapping

  • Database scalar function mapping does not provide a native way to use functions residing within PL/SQL packages. To work around this limitation, map the package and function to an Oracle synonym, then map the synonym to the EF Core function.

LINQ

  • LINQ queries that are used to query or restore historical (temporal) data are not supported.
  • LINQ queries that are used to query the DateOnly and TimeOnly types are not supported.
  • HasRowsAffectedReturnValue is not supported because Oracle does not support having a return value from a stored procedure. For example,
modelBuilder.Entity<Person>()
    .UpdateUsingStoredProcedure(
        "People_Update",
        storedProcedureBuilder =>
        {
            storedProcedureBuilder.HasRowsAffectedReturnValue(true)
        });
  • Certain LINQs cannot be executed against Oracle Database 21c or lower. Let us first imagine an entity model with the following entity:
public class MyTable
{
    public int Id { get; set; }
    public int? Value { get; set; }
}

The following LINQ will not work against Oracle Database 21c or lower:

var query = from t in context.Table
    group t.Id by t.Value
    into tg
    select new
    {
        A = tg.Key,
        B = context.Table.Where(t => t.Value == tg.Max() * 6).Max(t => (int?)t.Id)
    };

This is due to LINQ creating the following SQL query:

SELECT "t"."Value" "A", "t"."Id", (
    SELECT MAX("t0"."Id")
    FROM "MyTable" "t0"
    WHERE (("t0"."Value" = "t"."Id") OR ("t0"."Value" IS NULL AND MAX("t"."Id") IS NULL))) "B"
FROM "MyTable" "t"
GROUP BY "t"."Value"

The issue is because the inner select query uses a MAX function which refers to a column from the outer select query. Also the way in which the MAX function is used within the WHERE clause is not supported in Oracle Database. The same issue is also applicable when the MIN function is used.

  • Oracle DB doesn't support UPDATE queries with FROM clause in DB 21c or lower. So certain LINQs cannot be executed against Oracle Database which generate UPDATE query with FROM clause. For example, imagine an entity model with the following entities:
public class Blog
{
    public int Id { get; private set; }
    public string Name { get; set; }
    public List<Post> Posts { get; } = new();
}

public class Post
{
    public int Id { get; private set; }
    public string Title { get; set; }
    public string Content { get; set; }
    public DateTime PublishedOn { get; set; }
}

Trying to update the Blog.Name using below LINQ would throw 'ORA-00933: SQL command not properly ended'

var query = from blog in context.Set<Blog>().Where(c => c.Name == "MyBlog")
    join post in context.Set<Post>().Where(p => p.Title == "Oracle")
    on blog.Name equals post.Title
    select new { blog, post };
var updateQuery = query.ExecuteUpdate(s => s.SetProperty(c => c.blog.Name, "Updated"));

This is due to LINQ creating the following SQL query, which Oracle database does not support.

UPDATE "Blogs" "b"
SET "b"."Name" = N'Updated'
FROM (
    SELECT "p"."Id", "p"."BlogId", "p"."Content", "p"."PublishedOn", "p"."Title"
    FROM "Posts" "p"
    WHERE "p"."Title" = N'Oracle') "t"
WHERE (("b"."Name" = "t"."Title") AND ("b"."Name" = N'MyBlog'))
  • The PL/SQL returned by ToQueryString() does not execute successfully if the input to the LINQ query contains a TimeSpan. This is because in PL/SQL, interval value with precision is not accepted. Consider this example, imagine an entity model with the following entity:
public class Author
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTimeOffset Timeline { get; set; }
}

The following LINQ will not work:

var timeSpan = new TimeSpan(1000);
var authorsInChigley1 = context.Authors.Where(e => e.Timeline > DateTimeOffset.Now - timeSpan).ToQueryString();

Following is the PL/SQL that gets generated.

DECLARE
    l_sql     varchar2(32767);
    l_cur     pls_integer;
    l_execute pls_integer;
BEGIN
    l_cur := dbms_sql.open_cursor;
    l_sql := 'SELECT "a"."Id", "a"."Name", "a"."Timeline"
        FROM "Authors" "a"
        WHERE "a"."Timeline" > (SYSDATE - :timeSpan_0)';
    dbms_sql.parse(l_cur, l_sql, dbms_sql.native);
    dbms_sql.bind_variable(l_cur, ':timeSpan_0', INTERVAL '0 0:0:0.0001000' DAY(8) TO SECOND(7));
    l_execute:= dbms_sql.execute(l_cur);
    dbms_sql.return_result(l_cur);
END;

Scaffolding

  • ORA-50607 or similar error occurs when a table has multiple identity and/or sequence/trigger columns auto-generated. While scaffolding such a table, the .NET model generated contains the ValueGeneratedOnAdd fluent API for all the auto-generated columns. When executing a LINQ query on this table, an ORA-50607 or similar error is thrown that indicates only one identity column per table is allowed. As a workaround for column values generated by a sequence/trigger, replace the ValueGeneratedOnAdd() fluent API appended to the corresponding property/column with UseSequence(your sequence name). The sequence name is the Oracle database sequence name from which the column gets its value.
  • Scaffolding a table that uses Function Based Indexes is supported. However, the index will NOT be scaffolded.
  • Scaffolding a table that uses Conditional Indexes is not supported.

Sequences

  • A sequence cannot be restarted.
  • Extension methods related to SequenceHiLo is not supported, except for columns with Char, UInt, ULong, and UByte data types.

Copyright (c) 2025, 2025, Oracle and/or its affiliates.

Showing the top 20 packages that depend on Oracle.EntityFrameworkCore.

Packages Downloads
Quantum.Framework.Core.StandardLib
Package Description
79
Quantum.Framework.Core.StandardLib
Package Description
80
Quantum.Framework.Core.StandardLib
Package Description
83
Quantum.Framework.Core.StandardLib
Package Description
89
Quantum.Framework.Core.StandardLib
Package Description
97
Quantum.Framework.Core.StandardLib
Package Description
98
Quantum.Framework.Core.StandardLib
Package Description
102
Quantum.Framework.Core.StandardLib
Package Description
103
Quantum.Framework.Core.StandardLib
Package Description
104
Quantum.Framework.Core.StandardLib
Package Description
106
Quantum.Framework.Core.StandardLib
Package Description
116
Quantum.Framework.Core.StandardLib
Package Description
127
Quantum.Framework.Core.StandardLib
Package Description
166
Quantum.Framework.Core.StandardLib
Package Description
176
Quantum.Framework.Core.StandardLib
Package Description
184
Quantum.Framework.Core.StandardLib
Package Description
203

.NET 8.0

Version Downloads Last updated
9.23.26000 3 10/21/2025
9.23.90 13 07/04/2025
9.23.80 15 04/05/2025
9.23.60 22 12/24/2024
8.23.26000 3 10/21/2025
8.23.90 8 07/05/2025
8.23.80 13 04/05/2025
8.23.70 18 12/26/2024
8.23.60 24 11/04/2024
8.23.50 30 11/04/2024
8.23.40 535 05/03/2024
8.21.200 3 10/20/2025
8.21.190 10 07/06/2025
8.21.180 12 04/05/2025
8.21.170 17 12/26/2024
8.21.160 21 11/04/2024
8.21.150 29 11/06/2024
8.21.140 33 04/24/2024
8.21.121 29 12/29/2023
7.21.13 145 05/04/2024
7.21.12 23 05/25/2024
7.21.11 22 08/22/2023
7.21.9 24 06/13/2023
7.21.8 29 06/15/2023
6.23.3-dev 16 03/21/2025
6.21.170 16 12/26/2024
6.21.160 20 11/04/2024
6.21.150 21 12/07/2024
6.21.140 25 04/28/2024
6.21.130 30 01/31/2024
6.21.120 24 04/29/2024
6.21.110 136 08/07/2023
6.21.4 27 05/25/2024
5.21.90 26 06/15/2023
5.21.61 29 06/15/2023
5.21.5 23 05/01/2024
5.21.4 28 05/25/2024
5.21.1 31 05/01/2024
3.21.90 34 08/04/2023
3.21.61 25 06/15/2023
3.21.4 23 01/31/2024
3.19.180 24 06/15/2023
2.19.180 29 05/21/2024
2.19.110 27 05/01/2024
2.19.90 25 05/25/2024
2.19.80 23 05/25/2024
2.19.70 25 05/25/2024
2.19.60 26 05/25/2024
2.19.50 30 05/03/2024
2.19.30 26 05/25/2024