EF Core 1.1: Run Reverse Engineer from Code

EF Core includes the ability to reverse engineer a model from an existing database – using the Scaffold-DbContext command in Visual Studio, or the dotnet ef dbcontext scaffold command for .NET CLI. For an introduction, see Getting Started with an Existing Database.

The Problem

The commands mentioned above are designed to be invoked on a project. However, you may have a scenario where you want to invoke the reverse engineer pipeline from an external process.

As an example, you may be building some tooling that provides additional functionality over the EF Core reverse engineering capabilities.

The Solution

Below is an example of a console application thatĀ invokes the reverse engineer components and puts the output in C:\temp.

You will need to reference the design package for the provider you are using, in this case SQL Server, and the main design package for EF Core.

PM> Install-Package Microsoft.EntityFrameworkCore.SqlServer.Design
PM> Install-Package Microsoft.EntityFrameworkCore.Design

Warning: Internal Services In Use

In EF Core everything is public, including all the inner workings of EF that would historically have been internal. We did this so that folks that really want to mess around with internal services can do so without using reflection.

We put these services into *.internal namespaces and reserve the right to break the APIs at any point. This code listing uses a number of these services – so be aware that future versions of EF may break this code.

using Microsoft.EntityFrameworkCore.Scaffolding.Internal;
using Microsoft.Extensions.DependencyInjection;

namespace Sample
{
    class Program
    {
        static void Main(string[] args)
        {
            // Add base services for scaffolding
            var serviceCollection = new ServiceCollection()
                .AddScaffolding()
                .AddLogging();

            // Add database provider services
            var provider = new SqlServerDesignTimeServices();
            provider.ConfigureDesignTimeServices(serviceCollection);

            var serviceProvider = serviceCollection.BuildServiceProvider();

            var generator = serviceProvider.GetService<ReverseEngineeringGenerator>();
            var options = new ReverseEngineeringConfiguration
            {
                ConnectionString = @"Server=(localdb)\mssqllocaldb;Database=Northwind;Integrated Security=true",
                ProjectPath = @"C:\temp\",
                ProjectRootNamespace = "My.Namespace"
            };

            generator.GenerateAsync(options).Wait();
        }
    }
}