ODP.NET Core - Scaffold DB-Context

Viewed 12367

I am working with oracles odp.net core beta 3. Specifically, The dll is Oracle.ManagedDataAccess.Core.2.12.0-beta3. The project is to create a web api that sits on top of an oracle instance.

My question - Is the command "Scaffold-DBContext" supported with this provider. If so what am I doing wrong... I've made the attempt using a connection string similar to the following.

Data Source={databasename}/{TNS}.domain.local; User ID={UserName};Password={Password};

And the actual command in the Package Manager terminal

Scaffold-DbContext Data Source={databasename}/{TNS}.domain.local; User ID={UserName};Password={Password};" Oracle.ManagedDataAccess -OutputDir Models -Tables {TableName}

I get the following error which sugests it cannot fond a DesignTimeServiceAttribute in the provider assembly.

I also have Microsoft.EntityFrameworkCore.Tools (2.2.0) referenced which includes the design tools.

ERROR

    System.InvalidOperationException: Unable to find expected assembly attribute named DesignTimeProviderServicesAttribute in provider assembly Oracle.ManagedDataAccess. This attribute is required to identify the class which acts as the design-time service provider factory.
   at Microsoft.EntityFrameworkCore.Design.Internal.DesignTimeServicesBuilder.ConfigureProviderServices(String provider, IServiceCollection services, Boolean throwOnError)
   at Microsoft.EntityFrameworkCore.Design.Internal.DesignTimeServicesBuilder.Build(String provider)
   at Microsoft.EntityFrameworkCore.Design.Internal.DatabaseOperations.ScaffoldContext(String provider, String connectionString, String outputDir, String outputContextDir, String dbContextClassName, IEnumerable`1 schemas, IEnumerable`1 tables, Boolean useDataAnnotations, Boolean overwriteFiles, Boolean useDatabaseNames)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.ScaffoldContextImpl(String provider, String connectionString, String outputDir, String outputDbContextDir, String dbContextClassName, IEnumerable`1 schemaFilters, IEnumerable`1 tableFilters, Boolean useDataAnnotations, Boolean overwriteFiles, Boolean useDatabaseNames)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.ScaffoldContext.<>c__DisplayClass0_1.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
4 Answers

I experienced the problems that you experienced, even after downloading the ODP.NET Core driver for production (2.18.3, released on 20-Sept-2018 and available from nuget at https://www.nuget.org/packages/Oracle.ManagedDataAccess.Core/).

I contacted the Oracle community for help. A kind soul answered that there's another piece of the puzzle if we want to have a ready access to goodness such as "UseOracle." It is the Oracle provider for the Entity Framework Core. See the thread at https://community.oracle.com/thread/4180739.

The only other way to use it, to my knowledge and based on his answer, is the way described in the Oracle Help Center, Getting Started with ODP.NET Core (https://www.oracle.com/webfolder/technetwork/tutorials/obe/db/dotnet/ODPNET_Core_get_started/index.html).

I managed to scaffold it using

scaffold-dbcontext "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=1.1.1.1)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=MYdb)));Persist Security Info=True;User Id=MYUSER;Password=mypass;" Oracle.EntityFrameworkCore

But it's an unusable mess. tons of errors

Could not scaffold the foreign key 'XX.TABLE1(USER_ID,USER_ID)'. A key for 'ID,ID' was not found in the principal entity type 'Aspnetusers'.

Seems like Dapper is my friend...

I scaffolded some tables using this:

Scaffold-DbContext "Data Source=myDatabase.example.com/servicename; User ID=username;Password=password;" Oracle.EntityFrameworkCore -OutputDir myModels -Tables FIRSTTABALE,SECONDTABLE

The table names must be in uppercase and Oracle EntityFrameworkCore version was 2.19.30.

The produced models were totally fine. Maybe it depends on the EF Core version or on specifying the table names.

For oracle db use this into View->Other Windows->Package Manager Console:

Scaffold-DbContext "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT={your port}))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME={db SID})));User ID={username};Password={pass};Persist Security Info=True" Oracle.EntityFrameworkCore -Tables TABLE1, TABLE2, ..., TABLEK -OutputDir Models -force
Related