0
votes

I'm trying to generate migration in EF Core class library but to no avail so far. I'm using Package Manager Console (Visual Studio 2017 Community) to write a command like this :

PM> Add-Migration Update37

but I always get an error:

Unable to create an object of type 'DBContext'. Add an implementation of 'IDesignTimeDbContextFactory' to the project, or see https://go.microsoft.com/fwlink/?linkid=851728 for additional patterns supported at design time.

My solution structure :

enter image description here

As you can see I have 2 projects where MesDBModels is class library for which I would like to generate migration to Migrations folder. I have added a DummyProject in order to provide "Startup project" on .NETcore runtime. DummyProject also contains implementations of IDesignTimeDBContextFactory<> interface in DBContextFactory class. Also DummyProject contains reference to MesDBModels project.

MesDBModels.Database.DBContext :

using MesDBModels.FluentConfig;
using MesDBModels.Models;
using Microsoft.EntityFrameworkCore;

namespace MesDBModels.Database
{
public class DBContext : DbContext
{
    public DBContext(DbContextOptions<DBContext> options) : base(options) { }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.ApplyConfiguration(new AccessCardConfig());
        modelBuilder.ApplyConfiguration(new AlarmConfig());
        modelBuilder.ApplyConfiguration(new BitPositionConfig());
        modelBuilder.ApplyConfiguration(new MachineConfig());
        modelBuilder.ApplyConfiguration(new ParameterTemplateConfig());
        modelBuilder.ApplyConfiguration(new ReferenceConfig());
        modelBuilder.ApplyConfiguration(new ReferenceTemplateConfig());
        modelBuilder.ApplyConfiguration(new UserConfig());
        modelBuilder.ApplyConfiguration(new UserGroupConfig());
        modelBuilder.ApplyConfiguration(new UserPermissionConfig());

        base.OnModelCreating(modelBuilder);
    }

    public DbSet<AccessCard> AccessCards { get; set; }
    public DbSet<Alarm> Alarms { get; set; }
    public DbSet<AlarmDefinition> AlarmDefinitions { get; set; }
    public DbSet<AlarmPriority> AlarmPriorities { get; set; }
    public DbSet<BitPosition> BitPositions { get; set; }
    public DbSet<EventLog> EventLogs { get; set; }
    public DbSet<EventType> EventTypes { get; set; }
    public DbSet<Group> Groups { get; set; }
    public DbSet<Machine> Machines { get; set; }
    public DbSet<MachineState> MachineStates { get; set; }
    public DbSet<MachineStateDefinition> MachineStateDefinitions { get; set; }
    public DbSet<Permission> Permissions { get; set; }
    public DbSet<ParameterTemplate> ParameterTemplates { get; set; }
    public DbSet<ReferenceParameterHistory> ReferenceParameterHistory { get; set; }
    public DbSet<ParameterValueLimit> ParameterValueLimits { get; set; }
    public DbSet<Reference> References { get; set; }
    public DbSet<ReferenceParameterType> ReferenceParameterTypes { get; set; }
    public DbSet<ReferenceTemplate> ReferenceTemplates { get; set; }
    public DbSet<Session> Sessions { get; set; }
    public DbSet<Unit> Units { get; set; }
    public DbSet<UnitStatus> UnitStatuses { get; set; }
    public DbSet<User> Users { get; set; }
    public DbSet<UserGroup> UserGroups { get; set; }
    public DbSet<UserPermission> UsersPermissions { get; set; }
}

}

DummyProject.DBContextFactory :

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;

namespace MesDBModels
{
public class DBContextFactory : IDesignTimeDbContextFactory<DbContext>
{ 
    public DbContext CreateDbContext(string[] args)
    {
        var builder = new DbContextOptionsBuilder<DbContext>();
        builder.UseSqlServer(
            "Server=(local)\\serverName;Database=dbName;Trusted_Connection=True;MultipleActiveResultSets=true");

        return new DbContext(builder.Options);
    }
}

}

DummyProject.Program class :

using System;

namespace DummyProject
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}

So my question is : what am I doing wrong ? I have tried to put DBContextFactory class in MesDBModels project along with DBContext class but the result is the same. I have followed this : Using Entity Framework Core migrations for class library project and this : https://garywoodfine.com/using-ef-core-in-a-separate-class-library-project/ but maby I misunderstood something or done something wrong.

Please help.

1
I'd suggest to try it outside vs just to be sure you run your command in the correct (lib) project. Just open PowerShell, go to your LIB projects directory and run dotnet ef migration add xy and see what happens. (as far as I remember you have to set your lib project as startup project if you run it on pm console)Christoph Lütjen
Are you implementing IDesignTimeDbContextFactory<DbContext> or IDesignTimeDbContextFactory<DBContext>? The names are so close visually, I'm not sure if that's a typo or not, but if it's not, then most likely is the cause of the problem.Ivan Stoev

1 Answers

0
votes

You have made a typo in your

public class DBContextFactory : IDesignTimeDbContextFactory<DbContext>
{ 
    public DbContext CreateDbContext(string[] args)
    {
        var builder = new DbContextOptionsBuilder<DbContext>();
        builder.UseSqlServer(
            "Server=(local)\\serverName;Database=dbName;Trusted_Connection=True;MultipleActiveResultSets=true");

        return new DbContext(builder.Options);
    }
}

When trying to construct your DBContext, the framework looks for IDesignTimeDbContextFactory for DBContext, but you are instead implementing a factory for the base DbContext. Modify DbContext to DBContext in this code and it should work.