Skip to Main Content

ODP.NET

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Issues with ODP.NET in combination with EFCoreSecondLevelCacheInterceptor (invalid cast)

User_WPD5LFeb 7 2023

Hi,

We are having some issues with the ODP.NET driver in combination with a caching library EFCoreSecondLevelCacheInterceptor.

This library intercepts Commands and performs some logic to see if the results have been cached already. If that is the case, the interceptor returns an instance of this class:

EFTableRowsDataReader : DbDataReader

If the caching shouldn't happen, an OracleDataReader: DbDataReader is returned.

The issue we are facing has to do with the fact that inside the OracleRelationalCommandBuilderFactory.ExecuteReader and OracleRelationalCommandBuilderFactory.ExecuteReaderAsync a cast is done to OracleDataReader. That means that when using the EFCoreSecondLevelCacheInterceptor and its result, an InvalidCastException is thrown.

We understand the need for a specific OracleDataReader and we also have a possible (but not the cleanest) solution for this issue by creating a more specific OracleEFTableRowsDataReader that inherits from the OracleDataReader, but that class is sealed. (The same applies for the SqlDataReader from Microsoft, so this probably has a good reason of being sealed)

Would it be something you would be open for if the casting is done in a ‘safer’ way, maybe to just do nothing in case the dbDataReader2 is not of type OracleDataReader (since no more query needs to be executed in that case)?

Our StackTrace:


System.InvalidCastException: Unable to cast object of type 'EFCoreSecondLevelCacheInterceptor.EFTableRowsDataReader' to type 'Oracle.ManagedDataAccess.Client.OracleDataReader'. 
	at 
Oracle.EntityFrameworkCore.Storage.Internal.OracleRelationalCommandBuilderFactory.OracleRelationalCommandBuilder.OracleRelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken) 
	at 
Oracle.EntityFrameworkCore.Storage.Internal.OracleRelationalCommandBuilderFactory.OracleRelationalCommandBuilder.OracleRelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken) 
	at 
Oracle.EntityFrameworkCore.Storage.Internal.OracleRelationalCommandBuilderFactory.OracleRelationalCommandBuilder.OracleRelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken) 
	at
Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.InitializeReaderAsync(AsyncEnumerator enumerator, CancellationToken cancellationToken) 
	at 
Oracle.EntityFrameworkCore.Storage.Internal.OracleExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken) 
	at
Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()

Thanks in advance

This post has been answered by Alex Keh-Oracle on Jun 9 2023
Jump to Answer
Comments
Post Details
Added on Feb 7 2023
5 comments
11,201 views