Efcore: Fixed set of databases with identical schema (dotnet core + Pomelo MySQL)

Created on 27 Oct 2016  路  6Comments  路  Source: dotnet/efcore

Steps to reproduce

1) Take any pre-existing DbContext subclass that you have and create multiple, empty subclasses based on it.
2) In Startup#ConfigureServices, call services.AddDbContext for each of your new subclasses, pointing each Context at a different database. Unregister the shared parent class if it has been previously registered.
3) Run migrations against each database, via the command line (e.g. dotnet ef database update -c [Context]).

The issue

The migrations do not get applied as expected. I've resorted to copy-pasting the schemas into two separate classes for the time being.

Further technical details

EF Core version: 1.0.0
Operating system: Windows 10
Visual Studio version: N/A

closed-question

All 6 comments

Can you share the code from Startup.cs that registers your contexts?

Sure. I took this example from the Contoso University tutorial.

public void ConfigureServices(IServiceCollection services)
{
    ....
    services.AddDbContext<ASchoolContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
    services.AddDbContext<BSchoolContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
    ....
}

I suspect the context declaration code is also of interest, so:

using ContosoUniversity.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace ContosoUniversity.Data
{
    public class SchoolContext : DbContext
    {
        public SchoolContext(DbContextOptions<SchoolContext> options) : base(options)
        {
        }

        public DbSet<Course> Courses { get; set; }
        public DbSet<Enrollment> Enrollments { get; set; }
        public DbSet<Student> Students { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Course>().ToTable("Course");
            modelBuilder.Entity<Enrollment>().ToTable("Enrollment");
            modelBuilder.Entity<Student>().ToTable("Student");
        }
    }

    public class ASchoolContext : SchoolContext
    {
        public ASchoolContext(DbContextOptions<SchoolContext> options) : base(options)
        {
        }
    }

    public class BSchoolContext : SchoolContext
    {
        public BSchoolContext(DbContextOptions<SchoolContext> options) : base(options)
        {
        }
    }
}

@opensrcken Try changing the constructor for ASchoolContext to take DbContextOptions<ASchoolContext> and the constructor for BSchoolContext to take DbContextOptions<BSchoolContext>. Generally the generic parameter of the DbContextOptions in the constructor should match the generic parameter used in AddDbContext. This allows the correct options to be resolved from D.I. for each context.

@ajcvickers, that results in the following:

C:\Users\Ken\Documents\Visual Studio 2015\Projects\ContosoUniversity\src\ContosoUniversity\Data\SchoolContext.cs(37,80): error CS1503: Argument 1: cannot convert from 'Microsoft.EntityFrameworkCore.DbContextOptions<ContosoUniversity.Data.BSchoolContext>' to 'Microsoft.EntityFrameworkCore.DbContextOptions<ContosoUniversity.Data.SchoolContext>'
C:\Users\Ken\Documents\Visual Studio 2015\Projects\ContosoUniversity\src\ContosoUniversity\Data\SchoolContext.cs(30,80): error CS1503: Argument 1: cannot convert from 'Microsoft.EntityFrameworkCore.DbContextOptions<ContosoUniversity.Data.ASchoolContext>' to 'Microsoft.EntityFrameworkCore.DbContextOptions<ContosoUniversity.Data.SchoolContext>'
Build failed on 'ContosoUniversity'.

@opensrcken Change the parameter on the SchoolContext base class to be the non-generic DbContextOptions.

Thanks. For those who read in this in the future, what I ended up doing was making a constructor for each subclass in the base class:

        public SchoolContext(DbContextOptions<ASchoolContext> options) : base(options)
        {
        }
        public SchoolContext(DbContextOptions<BSchoolContext> options) : base(options)
        {
        }
Was this page helpful?
0 / 5 - 0 ratings