Entity Framwork migration script for multiple contexts fails over existing __MigrationHistory table

181 Views Asked by At

We have a project that contains multiple EntityFramework contexts, each with migrations enabled. Now when we create a full migration script using Update-Database -SourceMigration $initialDatabase -script we get a script per context.

This script however starts with something like this:

DECLARE @CurrentMigration [nvarchar](max)

IF object_id('[dbo].[__MigrationHistory]') IS NOT NULL
    SELECT @CurrentMigration =
        (SELECT TOP (1) 
        [Project1].[MigrationId] AS [MigrationId]
        FROM ( SELECT 
        [Extent1].[MigrationId] AS [MigrationId]
        FROM [dbo].[__MigrationHistory] AS [Extent1]
        WHERE [Extent1].[ContextKey] = N'Some.Configuration.Here'
        )  AS [Project1]
        ORDER BY [Project1].[MigrationId] DESC)

IF @CurrentMigration IS NULL
    SET @CurrentMigration = '0'

IF @CurrentMigration < '201506111916518_InitialCreate'
BEGIN
...

<migration code here>

...
END

Note how it gets the current migration using the ContextKey, and if it doesn't find it, it'll do the first migration.

Things get hairy because the first migration contains the code to create the __MigrationHistory table, which obviously already exists when you've already run the first script.

Is this some edge-case bug or am I doing something wrong here?

Thanks in advance

1

There are 1 best solutions below

0
On

EDIT: Sorry, I see the part about multiple contexts. For migrations, you might want to create a different context used solely for a single migration that includes all your tables. Julie Lehrman has a few articles on bounded contexts that may help:

https://msdn.microsoft.com/en-us/magazine/dn948104.aspx

https://msdn.microsoft.com/en-us/magazine/jj883952.aspx?f=255&MSPPError=-2147217396


That command creates an idempotent script that will run all the necessary migrations to get you up to date. So for a blank database with no __MigrationHistory table it will set @CurrentMigration = '0' and run the first migration that creates the table as well as all the others. If the database does exist with various migrations it runs the ones less than the highest migration already in the target database. Thus the naming convention (yyyyMMddHHmmss_xxxxx).

See https://msdn.microsoft.com/en-us/data/jj591621.aspx?f=255&MSPPError=-2147217396#idempotent