EFCore: Setting ConnectionString at runtime

Discussion of open issues, suggestions and bugs regarding ADO.NET provider for Oracle
Post Reply
cbiegner
Posts: 8
Joined: Thu 24 Nov 2016 15:52

EFCore: Setting ConnectionString at runtime

Post by cbiegner » Mon 12 Nov 2018 08:30

Hello,

using the Entity Developer I created a simple Model based on an existing database. Within a .Net Core ApiService I try to access the model an get an error:

The appsettings.json file contais the connectionstring:

Code: Select all

	"ConnectionStrings": {
		"FOOModelConnectionString": "User Id=FOOUSER;Password=FOOPASS;Server=FOOSRV;Direct=True;Sid=FOOSRV;Persist Security Info=True;License Key=AQuiteLongString"
	}
When setting a breakpoint in Startup.cs I can read the data from appsettings.json: (e.g. in Immediate Window)

Code: Select all

?Configuration.GetConnectionString("FOOModelConnectionString")
But when the model is accessed in code I get an error:
Connection string "FOOModelConnectionString" could not be found in the configuration file.
Taking a look at the auto-generated (by Entity Developer) FOO.FOOModel.cs I find teh folling Code:

Code: Select all

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
                if (!optionsBuilder.Options.Extensions.OfType<RelationalOptionsExtension>().Any(ext => !string.IsNullOrEmpty(ext.ConnectionString) || ext.Connection != null))
                  optionsBuilder.UseOracle(GetConnectionString("FOOModelConnectionString"));
            }
            CustomizeConfiguration(ref optionsBuilder);
            base.OnConfiguring(optionsBuilder);
        }

        private static string GetConnectionString(string connectionStringName)
        {
            System.Configuration.ConnectionStringSettings connectionStringSettings = System.Configuration.ConfigurationManager.ConnectionStrings[connectionStringName];
            if (connectionStringSettings == null)
                throw new InvalidOperationException("Connection string \"" + connectionStringName +"\" could not be found in the configuration file.");
            return connectionStringSettings.ConnectionString;
        }
So, what do I have to do to get this running? Change the auto-generated code? Or use a different file then appsettings.json? (I tried by adding web.config. but same error).

Just to make sure that there's no error in the model I created a .NET Framework Project that uses the model from above. When I added the connectionstring in app.config it all workes fine.

Shalex
Site Admin
Posts: 9040
Joined: Thu 14 Aug 2008 12:44

Re: EFCore: Setting ConnectionString at runtime

Post by Shalex » Fri 16 Nov 2018 18:21

You have generated the code with a standalone Entity Developer, haven't you?

Please open your .NET Core project and create the *.efml model with Entity Developer embedded into Visual Studio. In this case, the GetConnectionString method should look like this:

Code: Select all

        private static string GetConnectionString(string connectionStringName)
        {
            var configurationBuilder = new ConfigurationBuilder().AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
            var configuration = configurationBuilder.Build();
            return configuration.GetConnectionString(connectionStringName);
        }

entwicklungsensis
Posts: 17
Joined: Tue 21 Aug 2018 09:47

Re: EFCore: Setting ConnectionString at runtime

Post by entwicklungsensis » Fri 15 Nov 2019 16:16

Hello,
wir are using devart.data.oracle.efcore\9.9.872

After updateing to devart.data.oracle.efcore\9.9.872 the GetConnectionString(string connectionStringName) method ist generated like this (with Entity Developer embedded into Visual Studio 2017)

Code: Select all

        private static string GetConnectionString(string connectionStringName)
        {
            System.Configuration.ConnectionStringSettings connectionStringSettings = System.Configuration.ConfigurationManager.ConnectionStrings[connectionStringName];
            if (connectionStringSettings == null)
                throw new InvalidOperationException("Connection string \"" + connectionStringName +"\" could not be found in the configuration file.");
            return connectionStringSettings.ConnectionString;
        }
which leads to the error described above. connectionStringSettings is null.
Please correct this issue.

Regards
Thomas

Shalex
Site Admin
Posts: 9040
Joined: Thu 14 Aug 2008 12:44

Re: EFCore: Setting ConnectionString at runtime

Post by Shalex » Mon 18 Nov 2019 19:45

@entwicklungsensis

Target framework of your project is .NET Core 2.2, isn't it? Please open Model Settings and make sure that both settings are turned on:
* Use the connection string from appsettings.json
* Rewrite connection string during regeneration

If this doesn't help, send us a small test project so that we can reproduce the issue in our environment.

entwicklungsensis
Posts: 17
Joined: Tue 21 Aug 2018 09:47

Re: EFCore: Setting ConnectionString at runtime

Post by entwicklungsensis » Thu 28 Nov 2019 10:05

[deleted by entwicklungsensis]

Shalex
Site Admin
Posts: 9040
Joined: Thu 14 Aug 2008 12:44

Re: EFCore: Setting ConnectionString at runtime

Post by Shalex » Thu 28 Nov 2019 16:12

Please set Target framework of your project to .NET Core 2.2 (or .NET Standard 2.0) to stay with EF Core 2.2.6.

If this doesn't help, send us a test project for reproducing the issue.

Shalex
Site Admin
Posts: 9040
Joined: Thu 14 Aug 2008 12:44

Re: EFCore: Setting ConnectionString at runtime

Post by Shalex » Thu 28 Nov 2019 19:49

Thank you for the test project.

Your model in the project uses a custom template (Type=User), please disable it and enable a predefined EF Core template (Type=Predefined). It will generate the following method in Tocan.TocanNpsContext.cs:

Code: Select all

        private static string GetConnectionString(string connectionStringName)
        {
            var configurationBuilder = new ConfigurationBuilder().AddJsonFile("appsettings.json", optional: true, reloadOnChange: false);
            var configuration = configurationBuilder.Build();
            return configuration.GetConnectionString(connectionStringName);
        }
Now the code works.

Post Reply