Introduction

Learn how to setup Entity Framework 6 and Entity Framework Core connections for desktop applications for different environments encrypted and unencrypted connection strings.
  • All code presented is with SQL-Server. None of the connection methods are tied to SQL-Server so it will work with all Entity Framework providers.
  • Before running code samples
    • Run the following script to create and populate the database in Visual Studio or SSMS (SQL-Server Management Studio). Open the script and inspect the path where the database will be created as different version of SQL-Server will be install in different paths. 
    • With the Visual Studio solution open and viewing Solution Explorer right click on the top node and select restore NuGet packages if not using VS2019 which should auto restore packages.
  • Code First from existing database is used for both flavors of Entity Framework.

Strategy 

Since it is a bad idea to have a single database for development, staging and production there should be an environment for development, staging and production.

For a developer working on a project environments may be setup for one server and three mirrored databases. For example, SQL-Server Express edition is used with a database named Inventory, the development database would be named InventoryDev, staging InventoryStaging and production Inventory.

For a developer working on a project environments in a company usually have separate servers for each environment. This means the database will have the same name on each server while the database name is the same.

Dependent on which above case is used connection strings may be placed into a project’s application’s configuration file (app.config) then with some code and a conditional compilation symbol (under project properties build tab) access the proper connection string for where the application will be deployed.

The last step is to have instructions for deployment and changing environments, not simply for connection strings but any other configuration items and a rollback plan in the event the deployment fails or there is a bug in the application code.

Entity Framework 6

The connection string is stored in app.config under connectionStrings and accessed in the new constructor of the DbContext class.

using EntityFramework6Library.Models;
 
namespace EntityFramework6Library
{
 
    using System.Data.Entity;
 
 
    public partial class NorthWindContext : DbContext
    {
        public NorthWindContext() : base("name=NorthWindContext")
        {
        }
 
        public virtual DbSet<Contact> Contacts { get; set; }
        public virtual DbSet<ContactType> ContactTypes { get; set; }
 
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
        }
    }
}

For handling multiple environments modify the above class to have a conditional constructor as shown below. Next, add a connection string for each environment as shown in the following configuration file.

using EntityFramework6Library.Models;
 
namespace EntityFramework6Library
{
 
    using System.Data.Entity;
 
    public partial class NorthWindContext : DbContext
    {
 
#if Dev
        public NorthWindContext() : base("name=DevConnection")
#elif Staging
        public NorthWindContext() : base("name=StagingConnection")
#else
        public NorthWindContext() : base("name=ProductionConnection")
#endif
        { }
 
        public virtual DbSet<Contact> Contacts { get; set; }
        public virtual DbSet<ContactType> ContactTypes { get; set; }
 
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
        }
    }
}

Set a conditional compilation symbol (shown below is for the development environment).

Figure 1


Entity Framework Core (version 3 and below)

By default the connection is setup as follows, hard code unlike Entity Framework Core

#warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings.
                optionsBuilder.UseSqlServer("Data Source=.\\SQLEXPRESS;Initial Catalog=NorthWind2020;Integrated Security=True");

Even with a different in how a connection is configured what has been done with EF6 (Entity Framework 6) can be applied to EF Core. Going with the standard connection string above the line is replaced with the following.

Notes:
  • For those familiar with a DbContext class figure 2 is for EF Core
  • Note the third using statement, this requires a reference to System.Configuration.
Figure 2

using Microsoft.EntityFrameworkCore;
using EntityFrameworkCoreLibrary.Models;
using static System.Configuration.ConfigurationManager;
 
namespace EntityFrameworkCoreLibrary.Contexts
{
    public partial class NorthWindContext : DbContext
    {
        public NorthWindContext()
        {
        }
 
        public NorthWindContext(DbContextOptions<NorthWindContext> options)
            : base(options)
        {
        }
 
        public virtual DbSet<ContactType> ContactType { get; set; }
        public virtual DbSet<Contacts> Contacts { get; set; }
 
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
                var environment = "";
 
#if Dev
                environment = "DevConnection";
#elif Staging
                environment = "StagingConnection";
#else
                environment = "ProductionConnection";
#endif
                optionsBuilder.UseSqlServer(AppSettings[environment]);
 
            }
        }
 
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.ApplyConfiguration(new ContactTypeConfiguration());
            modelBuilder.ApplyConfiguration(new ContactsConfiguration());
 
            OnModelCreatingPartial(modelBuilder);
        }
 
        partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
    }
}

The app.config file a section for appSetting is added with connection strings for each environment which can be seen here. Next set the environment as done in figure 1 for EF6.

Entity Framework Core with encryption

The exact same logic is used as the last example except the following class is used to encrypt and decrypt the connection string.Contains two methods, one to encrypt, one to decrypt a string used to secure a connection string for Entity Framework Core code first.

The level of encrypt/decryption used here was picked at random, there are less and more secure methods, what a developer selects should be dependent on if they believe someone will be able to hack the application or not.

See encrypted connection in the app.config file.

VB.NET coding

For those working with EF Core there is an example to follow which works the same as C# examples above.

Summary

Code has been presented to allow a developer to setup Entity Framework 6 and Entity Framework Core to work in development, staging and production along with securing connection strings from prying people poking around.

Note that even with encryption user names and password should not be stored, instead a better idea is to use active directory and/or creating users and roles in SQL-Server.

Don't care for conditional compiling for different environments, an alternative is to setup a static class with logic to deal with different environments which will be presented in a future article. To get an idea of the basics see ApplicationSettings class.

See also

Source code

The following GitHub repository contains all code for this article.