Exploring Azure with Code First

For my upcoming talk at Codemash I decided to create a brand new API with which to use as the source data for demos, the API would feature data from Starcraft 2, mostly around unit information for now.

Initially, I wanted to use .NET Core with Entity Framework Code First for this, but after a few hours it was clear that there is still not enough maturity in this space to allow me to organize the solution the way I want (separate library project for all EF models and context). That being the case, I decided to work the .NET Framework 4.6.1.

I was able to easily setup my Context and models using code first. I enabled migrations and built the database up. I considered this part difficult as StarCraft features a lot of interesting relationships between units for each of the three races. In the end I was able to setup the database with what I wanted. In addition to annotated relationships in each of the models I had to include some context based customizations, below is my class for the Context:

public class StarcraftContext : DbContext, IContext
{
    public IDbSet<Unit> Units { get; set; }
    public IDbSet<UnitDependency> UnitDependencies { get; set; }
    public IDbSet<UnitProduction> UnitProductions { get; set; }

    public StarcraftContext() : base("StarcraftConnectionString")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<UnitProduction>()
            .HasKey(x => x.UnitId);

        modelBuilder.Entity<Unit>()
            .HasRequired(x => x.Production)
            .WithRequiredPrincipal(x => x.Unit)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<UnitProduction>()
            .HasRequired<Unit>(x => x.ProducedBy)
            .WithMany(x => x.UnitsProduced)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<UnitDependency>()
            .HasRequired(x => x.TargetUnit)
            .WithMany(x => x.Dependencies)
            .WillCascadeOnDelete(false);
    }
}

Essentially, I wanted each Unit to exist in a single table with other tables indicating their dependencies and where they can be produced from. The model is still not complete as I have not found the best way to represent the Tech Lab (Terran) requirement or the Archon (Protoss) production but it will only be minor tweaks.

Once I had this created an API calls to return me all units or units by faction I was ready to deploy to Azure. That is where the real difficulty came in.

Azure App Service

Not to date myself too much, but my preference for things like this has always been the Mobile Service apps on Azure, those are merged now with Web apps to create the App Service – this would be the first time I setup an instance fresh.

Deployment was made difficult by a sporadic error I would receive in Visual Studio telling me that a key already exists each time I would try to publish. I found the only consistent way to overcome this was to recreate the solution, which happened a few times given the struggles with getting the Code First Migrations to run when deployed to Azure (more on that in a bit). I now believe it had to do with me rewinding the git HEAD as I undid my changes.

Reading this tutorial (https://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application) and a few others the suggestion was made to create the Publish profile such that Execute Code First Migrations (runs on application start) would force the migrations to run. And indeed this is true, however, there was one thing missing, one thing that this and other tutorials failed to mention.

When Migrations are enabled Visual Studio (or rather the EF tool run as part of Enable-Migrations cmdlet) creates a class called Configuration. This class configures the migrations. Funny enough in its constructor there is a single line:

public Configuration()
{
#if DEBUG
    AutomaticMigrationsEnabled = false;
#else
    AutomaticMigrationsEnabled = true;
#endif
}

Interestingly, and why its not mentioned or handled for you (with the selection of the checkbox) this properly must be enabled (or set to True). Since I am not sure what effect this will have when I am working locally I choose to use a PreProcessor directive to check the compile type. When I published with this change and hit the API the database migrations ran and the database was setup as expected.

With this change I was able to deploy the starting point of my Starcraft API to Azure and can begin using the Unit list in demos, as well as using it to build a site which allows me to learn Angular 2. More on that later. Cheers.

Leave a comment