We are using EF, Oracle.ManagedDataAccess, Oracle.ManagedDataAccess.EntityFramework (.NET Framework 4.8) for quite several years.
After upgrading to 23.26.0 from 23.8.0 we come to a problem where procedures on packages cant be resolved by EF model's object context.
More specifically the error message we get is:
System.ArgumentOutOfRangeException: Length cannot be less than zero.
Parameter name: length
While the error stack shows:
String.Substring(Int32 startIndex, Int32 length)
SqlGenerator.QuoteIdentifier_storeFunctionName(String name)
SqlGenerator.GenerateFunctionSql(DbFunctionCommandTree tree, CommandType& commandType, List`1& parameters)
SqlGenerator.GenerateSql(DbCommandTree tree, EFOracleProviderManifest providerManifest, EFOracleVersion sqlVersion, List`1& parameters, CommandType& commandType, HashSet`1& ListOfParamsToMakeUnicodeFalse)
EFOracleProviderServices.CreateCommand(EFOracleProviderManifest providerManifest, DbCommandTree commandTree)
EFOracleProviderServices.CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree)
DbProviderServices.CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree, DbInterceptionContext interceptionContext)
DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree, DbInterceptionContext interceptionContext)
DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree)
EntityCommandDefinition.ctor(DbProviderFactory storeProviderFactory, DbCommandTree commandTree, DbInterceptionContext interceptionContext, IDbDependencyResolver resolver, BridgeDataReaderFactory bridgeDataReaderFactory, ColumnMapFactory columnMapFactory)
<5 more frames...>
ObjectContext.CreateFunctionObjectResult[TElement](EntityCommand entityCommand, ReadOnlyCollection`1 entitySets, EdmType[] edmTypes, ExecutionOptions executionOptions)
<>c__DisplayClass161_0`1.<ExecuteFunction>b__1()
ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
<>c__DisplayClass161_0`1.<ExecuteFunction>b__0()
DefaultExecutionStrategy.Execute[TResult](Func`1 operation)
ObjectContext.ExecuteFunction[TElement](String functionName, ExecutionOptions executionOptions, ObjectParameter[] parameters)
ObjectContext.ExecuteFunction[TElement](String functionName, MergeOption mergeOption, ObjectParameter[] parameters)
ObjectContext.ExecuteFunction[TElement](String functionName, ObjectParameter[] parameters)
when trying to call the “P_PERSONNEL_PKG.GETVALUES” procedure , it appears that SqlGenerator.QuoteIdentifier_storeFunctionName to change a bit causing the exception.
If we downgrade to 23.8.0 everything works fine.
The following console app completely demos the issue.
program.cs
using EntityFramework.Functions;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.ModelConfiguration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace QuoteIdentifierIssue
{
public class EmployeeHoliday
{
public long HolidayId { get; set; }
public string HolidayDescription { get; set; }
public DateTime? HolidayDate { get; set; }
}
public class EmployeeHolidayConfiguration : ComplexTypeConfiguration
{
public EmployeeHolidayConfiguration()
{
Property(a => a.HolidayId)
.HasColumnName("HOLIDAYID");
Property(a => a.HolidayDescription)
.HasColumnName("HOLIDAYDESCRIPTION");
Property(a => a.HolidayDate)
.HasColumnName("HOLIDAYDATE");
}
}
class Program
{
public class MyContext : DbContext
{
public MyContext()
: base("DefaultConnection")
{
Database.SetInitializer(null);
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.HasDefaultSchema("MYSCHEMA");
modelBuilder.Configurations.Add(new EmployeeHolidayConfiguration());
modelBuilder.AddFunctions();
}
[Function(FunctionType.StoredProcedure, nameof(GetValues), StoreFunctionName = "P_PERSONNEL_PKG.GETVALUES")]
public ObjectResult GetValues()
{
var result = this.ObjectContext().ExecuteFunction(nameof(GetValues));
return result;
}
}
static void Main(string[] args)
{
using (var context = new MyContext())
{
context.Database.Log = Console.WriteLine;
var results = context.GetValues();
Console.WriteLine(results);
}
}
}
}
app.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<section name="oracle.manageddataaccess.client" type="OracleInternal.Common.ODPMSectionHandler, Oracle.ManagedDataAccess, Version=4.122.23.1, Culture=neutral, PublicKeyToken=89b483f429c47342" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>
<entityFramework>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
<provider invariantName="Oracle.ManagedDataAccess.Client" type="Oracle.ManagedDataAccess.EntityFramework.EFOracleProviderServices, Oracle.ManagedDataAccess.EntityFramework, Version=6.122.23.1, Culture=neutral, PublicKeyToken=89b483f429c47342" />
</providers>
</entityFramework>
<connectionStrings>
<add name="DefaultConnection" providerName="Oracle.ManagedDataAccess.Client" connectionString="User Id=MYSCHEMA;Password=MYSCHEMA;Data Source=//YOURSERVER:1521/HOST" />
<add name="OracleDbContext" providerName="Oracle.ManagedDataAccess.Client" connectionString="User Id=oracle_user;Password=oracle_user_password;Data Source=oracle" />
</connectionStrings>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.5.0" newVersion="4.0.5.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.1.0" newVersion="6.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.4.0" newVersion="4.0.4.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.4.0" newVersion="4.2.4.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Numerics.Vectors" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.5.0" newVersion="4.1.5.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Text.Json" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Formats.Asn1" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Text.Encodings.Web" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<oracle.manageddataaccess.client>
<version number="*">
<edmMappings>
<edmNumberMapping>
<add NETType="bool" MinPrecision="1" MaxPrecision="1" DBType="Number" />
<add NETType="byte" MinPrecision="2" MaxPrecision="3" DBType="Number" />
<add NETType="int16" MinPrecision="4" MaxPrecision="5" DBType="Number" />
<add NETType="int32" MinPrecision="6" MaxPrecision="10" DBType="Number" />
<add NETType="int64" MinPrecision="11" MaxPrecision="19" DBType="Number" />
</edmNumberMapping>
</edmMappings>
<implicitRefCursor>
<storedProcedure name="P_PERSONNEL_PKG.GETVALUES">
<refCursor name="PORESULT">
<bindInfo mode="Output" />
</refCursor>
</storedProcedure>
</implicitRefCursor>
</version>
</oracle.manageddataaccess.client>
<system.data>
<DbProviderFactories>
<remove invariant="Oracle.ManagedDataAccess.Client" />
<add name="ODP.NET, Managed Driver" invariant="Oracle.ManagedDataAccess.Client" description="Oracle Data Provider for .NET, Managed Driver" type="Oracle.ManagedDataAccess.Client.OracleClientFactory, Oracle.ManagedDataAccess, Version=4.122.23.1, Culture=neutral, PublicKeyToken=89b483f429c47342" />
</DbProviderFactories>
</system.data>
</configuration>
packages.config
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="EntityFramework" version="6.5.1" targetFramework="net48" />
<package id="EntityFramework.Functions" version="1.5.0" targetFramework="net48" />
<package id="Microsoft.Bcl.AsyncInterfaces" version="10.0.0" targetFramework="net48" />
<package id="Oracle.ManagedDataAccess" version="23.26.0" targetFramework="net48" />
<package id="Oracle.ManagedDataAccess.EntityFramework" version="23.26.0" targetFramework="net48" />
<package id="System.Buffers" version="4.6.1" targetFramework="net48" />
<package id="System.Diagnostics.DiagnosticSource" version="10.0.0" targetFramework="net48" />
<package id="System.Formats.Asn1" version="10.0.0" targetFramework="net48" />
<package id="System.IO.Pipelines" version="10.0.0" targetFramework="net48" />
<package id="System.Memory" version="4.6.3" targetFramework="net48" />
<package id="System.Numerics.Vectors" version="4.6.1" targetFramework="net48" />
<package id="System.Runtime.CompilerServices.Unsafe" version="6.1.2" targetFramework="net48" />
<package id="System.Text.Encodings.Web" version="10.0.0" targetFramework="net48" />
<package id="System.Text.Json" version="10.0.0" targetFramework="net48" />
<package id="System.Threading.Tasks.Extensions" version="4.6.3" targetFramework="net48" />
<package id="System.ValueTuple" version="4.6.1" targetFramework="net48" />
</packages>
DB package-procedure
procedure GetValues(poresult out sys_refcursor) as
begin
open poresult for
Select Hcl_id as HolidayId,
Hcl_Descr AS HolidayDescription,
HolidayDate
from holidays;
end GetValues;
Please advise.