Using TFS Build to Deploy Entity Framework Database Migrations with Migrate.exe

Posted · 11 Comments

In the discussion thread for my DevOps Skills class at Pluralsight, I got a question about how to deploy database changes in a build using Entity Framework Migrations (aka. EF Code First Migrations).  It’s actually pretty easy and it all comes down to a tool that comes with Entity Framework called migrate.exe.  When you deploy your Entity Framework migrations using the Visual Studio Package Manager and call ‘Update-Database’, it ultimately ends up calling the same logic that is used by migrate.exe.  Pretty much anything that you can call from the command line can be hooked into a TFS automated build.

To keep everything easy and clean in your build, I’d recommend creating a directory in the artifacts folder of your build that will contain everything that you need to do your EF migrate calls.  What you’ll need are the DLLs and config file for your Entity Framework code plus the contents of the Entity Framework NuGet Package folder.  I usually create a folder called ‘for-deploy’ and then put the various pieces of my deployments in subfolders.  What you end up with is a folder that looks like the screenshot below.  You’ve got a folder in the artifacts directory of your build (“$(build.artifactstagingdirectory)\for-deploy\ef-database”) that has the DLLs and config file for my app’s entity framework code plus the bits for Entity Framework itself — most importantly, migrate.exe.

Deployment directory in my build that contains the Entity Framework DLLs for my app plus the contents of the Entity Framework NuGet package.

In the build definition, you just start with a standard default build for a Visual Studio project.  From there, you’ll add two Copy Files tasks and a Command Line task.  The first task copies the Entity Framework package contents.  Next, copy the Entity Framework data access DLLs for your project.  Finally, use a Command Line task to call Migrate.exe to deploy the database.

Create the for-deploy directory and deploy the database with Migrate.exe

Here are the arguments for the build steps.  The values here are example values and you’ll need to change them to match the names of your code and Entity Framework version that you’re using.  I’m also only specifying the non-default values for the steps.  If I don’t mention a value, don’t change the default.

STEP #1
Step Type: Copy Files
Step Name: Copy Entity Framework NuGet Package Contents Step
Source Folder: 
$(build.sourcesdirectory)\Benday.WebAppWithEF\packages\EntityFramework.6.1.3\tools\
Target Folder:
$(build.artifactstagingdirectory)\for-deploy\ef-database
Advanced / Over Write: True

STEP #2
Step Type: Copy Files
Step Name: Copy Application DLLs for my Entity Framework code
Source Folder: 
$(build.sourcesdirectory)\Benday.WebAppWithEF/Benday.WebAppWithEF.Core/bin/$(BuildConfiguration)
Target Folder:
$(build.artifactstagingdirectory)\for-deploy\ef-database
Advanced / Over Write: True

STEP #3
Step Type: Command Line
Step Name: Deploy database using Migrate.exe
Tool: 
$(build.artifactstagingdirectory)\for-deploy\ef-database\migrate.exe
Arguments:
Benday.WebAppWithEF.Core.dll /startupConfigurationFile=Benday.WebAppWithEF.Core.dll.config
Advanced / Working folder: 
$(build.artifactstagingdirectory)\for-deploy\ef-database

After you’ve added these steps to your build, be sure to save your changes then run the build.

NOTE: if the connection string in the app.config / web.config is not appropriate for your build environment, you’ll need to modify it before running the Migrate.exe step.

I hope this helps.

-Ben

 

— Need help getting Entity Framework Migrations included into your build, test, and deploy process?  Want some assistance getting a DevOps flow flowing at your company?  Looking training on this stuff?  We can help.  Drop us a line at info@benday.com


11 Responses to "Using TFS Build to Deploy Entity Framework Database Migrations with Migrate.exe"
  1. jbssa says:

    Thank you for the response, sorry it’s taken so long to get back to you. But why are you using the 6.1 migrate exe for ef7? Does this mean that we need to get both versions for this to work? ef 7 uses the dotnet ef migrations command contained in ef.dll

  2. Murali Krishnaraj says:

    Hi Ben

    This step applies the changes to the database. Is that the correct place to do database migration? If i have a release definition using this build that deploys the changes to different environment(Dev,Test & Prod), how to handle this scenario?.

    • Ben Day says:

      @Murali — in that case, it sounds like you want to do the database deployment from the release definition rather than the build definition. In the blog post, I suggest 3 steps that you should add to the build definition. To make this work from a Release, I’d leave Step #1 and Step #2 in the build definition and then move Step #3 to the release definition. NOTE: you’ll probably need to adjust the “Tool” and “Working Folder” paths in Step #3 because the source paths are probably a little different for the Release.

      -Ben

      • Murali Krishnaraj says:

        HI Ben,

        I moved the #3 to release definition. When i tested these steps at build level it worked. After moving to release definition it is failing with error
        ” A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 26 – Error Locating Server/Instance Specified)”

        I checked the Connection string and it is exactly same values and also the Agent is same. Any thoughts?

  3. Ben says:

    Hi,
    great article, that worked!
    cheers, Ben

  4. Kristi says:

    Hi Ben – I’m trying to get this working, but I’m confused about what you mean when you say:

    “’I’d recommend creating a directory in the artifacts folder of your build.”

    Where is the artifacts folder? Is it on my local machine (I

    • Kristi says:

      I forgot to finish my comment. However, I figured it out (I think). I didn’t create a local agent on my machine – I’ve been doing everything online. So that’s why I can’t find the file structure as shown above on my local machine. I added the 3 steps you list, but I received an error that I didn’t have a release definition in my bin folder for step 2. So I have missed something.

      • Kristi says:

        Update – my file structure is a little different, so after some modifications, I was able to get the build to complete the two file copies and start the migrate.exe. However, it’s failing with the error:
        Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly ‘EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089’ or one of its dependencies. The system cannot find the file specified.

        My application has EF 6.1.3

        • Ben Day says:

          Hi Kristi —

          It sounds like you got a lot of stuff working. That “could not load file or assembly” error will probably get fixed if you put the entity framework dlls into that same folder as migrate.exe. Migrate.exe is basically saying that it can’t find the core stuff for doing entity framework (EntityFramework.dll) and since it can’t find that, it bombs out.

          -Ben

 

© 2016 Benjamin Day Consulting, Inc.
Brookline, MA
617-645-0188
info@benday.com | |