Не удалось создать миграции после обновления до ASP.NET Core 2.0

После обновления до ASP.NET Core 2.0 я больше не могу создавать миграции.

Я получаю

"Произошла ошибка при вызове метода" BuildWebHost "в классе" Программа ". Продолжение без поставщика приложений. Ошибка: Произошла одна или несколько ошибок. (Не удается открыть базу данных"... ", запрошенную логин. Ошибка входа в систему. Ошибка входа для пользователя"..."

и

"Невозможно создать объект типа" MyContext ". Добавить реализацию 'IDesignTimeDbContextFactory' для проекта или посмотреть https://go.microsoft.com/fwlink/?linkid=851728 для дополнительных паттернов поддерживается во время разработки".

Команда, которую я ранее выполнял, была $ dotnet ef migrations add InitialCreate --startup-project "..\Web" (из проекта/папки с DBContext).

Строка подключения: "Server=(localdb)\\mssqllocaldb;Database=database;Trusted_Connection=True;MultipleActiveResultSets=true"

Это моя Program.cs

 public class Program
{
    public static void Main(string[] args)
    {
        BuildWebHost(args).Run();
    }

    public static IWebHost BuildWebHost(string[] args) =>
       WebHost.CreateDefaultBuilder(args)
           .UseStartup<Startup>()
           .Build();
}

Ответ 1

Вы можете добавить класс, который реализует IDesignTimeDbContextFactory внутри вашего веб-проекта.

Вот пример кода:

public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<CodingBlastDbContext>
{
    public CodingBlastDbContext CreateDbContext(string[] args)
    {
        IConfigurationRoot configuration = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json")
            .Build();
        var builder = new DbContextOptionsBuilder<CodingBlastDbContext>();
        var connectionString = configuration.GetConnectionString("DefaultConnection");
        builder.UseSqlServer(connectionString);
        return new CodingBlastDbContext(builder.Options);
    }
}

Затем перейдите к вашему проекту базы данных и выполните следующую команду из командной строки:

dotnet ef migrations add InitialMigration -s ../Web/

dotnet ef database update -s ../Web/

-s stands for startup project and ../Web/ is the location of my web/startup project.

ресурс

Ответ 2

Нет необходимости для IDesignTimeDbContextFactory.

Бежать

add-migration initial -verbose

что раскроет детали под

Произошла ошибка при доступе к IWebHost в классе "Программа". Продолжая без поставщика услуг приложения.

предупреждение, которое является основной причиной проблемы.

В моем случае проблема заключалась в том, что ApplicationRole: IdentityRole<int> и вызов services.AddIdentity<ApplicationUser, IdentityRole>() вызывали приведенную ниже ошибку.

System.ArgumentException: GenericArguments[1], 'Microsoft.AspNetCore.Identity.IdentityRole', 
on 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore'9[TUser,TRole,TContext,
TKey,TUserClaim,TUserRole,TUserLogin,TUserToken,TRoleClaim]' violates the constraint of type 'TRole'.
---> System.TypeLoadException: GenericArguments[1], 'Microsoft.AspNetCore.Identity.IdentityRole', 
on 'Microsoft.AspNetCore.Identity.UserStoreBase'8[TUser,TRole,TKey,TUserClaim,
TUserRole,TUserLogin,TUserToken,TRoleClaim]' violates the constraint of type parameter 'TRole'.

Ответ 3

В моем случае причиной проблемы было несколько запускаемых проектов. В моем решении три проекта: Mvc, Api и Dal. DbContext и Миграции в проекте Dal.

Я настроил несколько проектов запуска. Оба проекта Mvc и Api были запущены, когда я нажал "Пуск". Но в этом случае я получал эту ошибку.

"Невозможно создать объект типа" MyContext ". Добавьте реализацию проекта" IDesignTimeDbContextFactory "в проект или обратитесь к https://go.microsoft.com/fwlink/?linkid=851728 за дополнительными шаблонами, поддерживаемыми во время разработки".

Я мог бы успешно добавить миграцию после установки Mvc в качестве единственного запускаемого проекта и выбора Dal в консоли диспетчера пакетов.

Ответ 4

public class Program
{
    public static void Main(string[] args)
    {
        BuildWebHost(args).Run();
    }

    public static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .Build();
    }
}

Просто переименуйте BuildWebHost() в CreateWebHostBuilder(), потому что миграции используют этот метод по умолчанию.

Ответ 5

Лучшее решение:

Решение 1:

Установите для проекта веб-приложения значение "Установить как стартовый проект"

Откройте консоль диспетчера пакетов из меню ToolsNuGet Package MangerPackage Manager Console в Visual Studio, чтобы выполнить следующие команды.

Add-Migration Init -Verbose

Примечание. Используйте опцию –verbose, чтобы просмотреть применяется к целевой базе данных. Содержит подробные ошибки.

Решение 2:

Если ваш стартовый проект представляет собой приложение ASP.NET Core, инструменты пытаются получить объект DbContext у поставщика услуг приложения.

Сначала инструмент пытается получить поставщика услуг, вызывая Program.BuildWebHost() и получая доступ к свойству IWebHost.Services.

Добавьте этот метод после метода Main в Program.cs

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .Build();

Обновление .NET Core 2.2

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
} 

Обновить .NET Core 3.0

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

Решение 3::

Убедитесь, что вы добавили Dbcontext к внедрению зависимости:  AddDbContext<TContext> сделает ваш тип DbContext, TContext и соответствующий DbContextOptions<TContext> доступным для инъекции из сервисного контейнера. Это требует добавления аргумента конструктора к вашему типу DbContext, который принимает DbContextOptions<TContext>.

Пример: В Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<AppDbContext>(options => options.UseSqlServer(connectionString));
}

AppDbContext code:

public class AppDbContext: DbContext
{
    public AppDbContext(DbContextOptions<BloggingContext> options)
      :base(options)
    { }

}

Ответ 6

В AppContext.cs кроме класса AppContext добавьте еще один класс:

// required when local database deleted
public class ToDoContextFactory : IDesignTimeDbContextFactory<AppContext>
{
    public AppContext CreateDbContext(string[] args)
    {
        var builder = new DbContextOptionsBuilder<AppContext>();
          builder.UseSqlServer("Server=localhost;Database=DbName;Trusted_Connection=True;MultipleActiveResultSets=true");
        return new AppContext(builder.Options);
    }
}

Это решит вашу вторую проблему:

"Невозможно создать объект типа" MyContext ". Добавьте реализацию проекта" IDesignTimeDbContextFactory ",

После этого вы сможете добавить-Первичный запуск и выполнить его, выполнив команду update-database. Однако, если вы выполняете эти команды, когда в вашем локальном SqlServer нет базы данных, вы получите предупреждение, подобное первой ошибке: "Ошибка

произошел при вызове метода "BuildWebHost" в классе "Программа"... Авторизация не удалась. Ошибка входа для пользователя "..."

Но это не ошибка, потому что миграция будет создана и может быть выполнена. Поэтому просто проигнорируйте эту ошибку в первый раз, а последняя, ​​поскольку Db будет существовать, больше не повторится.

Ответ 7

убедитесь, что у вас есть ссылка

<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.0.0" />

Ответ 8

Что-то, что действительно помогло мне, было в этой статье: https://elanderson.net/2017/09/unable-to-create-an-object-of-type-applicationdbcontext-add-an-implementation-of-idesigntimedbcontextfactory/

Основная идея заключается в том, что при переходе от ядра .net от 1 до 2 вся инициализация db должна быть удалена из StartUp.cs и в Program.cs. В противном случае задачи EF пытаются и запускать ваши базы данных при выполнении задач.

"В официальных документах по миграции есть хороший раздел ( https://docs.microsoft.com/en-us/ef/core/miscellaneous/1x-2x-upgrade) под названием" Переместить код инициализации базы данных ", который мне показался пропустили.Таким образом, прежде чем вы окажетесь на кроличьих отверстиях, как будто я убедился, что это не то, что заставляет вас добавить реализацию IdesignTimeDbContextFactory."

Ответ 9

Вы можете попробовать это решение из это обсуждение, которое было вдохновлено этим сообщением.

public static IWebHost MigrateDatabase(this IWebHost webHost)
{
    using (var scope = webHost.Services.CreateScope())
    {
        var services = scope.ServiceProvider;

        try
        {
            var db = services.GetRequiredService<MyContext>();
            db.Database.Migrate();
        }
        catch (Exception ex)
        {
            var logger = services.GetRequiredService<ILogger<Program>>();
            logger.LogError(ex, "An error occurred while migrating the database.");
        }
    }

    return webHost;
}
public static void Main(string[] args)
{
    BuildWebHost(args)
        .MigrateDatabase()
        .Run();
}

Ответ 10

У меня была эта проблема, и она была решена с помощью Set → Web Application (Included Program.cs) Project to → "Set as Startup Project"

Затем запустите → add-migration initial -verbose

в консоли диспетчера пакетов

Сделать стартовым проектом

Ответ 11

Если вы хотите избежать этой вещи IDesignTimeDbContextFactory: просто убедитесь, что вы не используете какой-либо метод Seed при запуске. Я использовал статический метод seed при запуске, и это вызывало эту ошибку для меня.

Ответ 12

Раньше вы настраивали исходные данные в методе Configure в Startup.cs. В настоящее время рекомендуется использовать метод Configure только для настройки конвейера запросов. Код запуска приложения принадлежит методу Main.

Восстановленный основной метод. Добавьте следующие ссылки в Program.cs:

с использованием Microsoft.Extensions.DependencyInjection;

с помощью MyProject.MyDbContextFolder;

public static void Main(string[] args)
{
    var host = BuildWebHost(args);

    using (var scope = host.Services.CreateScope())
    {
        var services = scope.ServiceProvider;
        try
        {
            var context = services.GetRequiredService<MyDbConext>();
            DbInitializer.Initialize(context);
        }
        catch (Exception ex)
        {
            var logger = services.GetRequiredService<ILogger<Program>>();
            logger.LogError(ex, "An error occurred while seeding the database.");
        }
    }

    host.Run();
}

Ответ 13

Есть проблема с ef seeding db из Startup.Configure в 2.0... вы все равно можете сделать это с помощью этой работы. Протестировано и отлично работает

https://garywoodfine.com/how-to-seed-your-ef-core-database/

Ответ 14

В моем случае я получил проблему, потому что у меня был метод с именем SeedData.EnsurePopulated(), вызываемый в моем файле Startup.cs.

public class Startup
{
    public Startup(IConfiguration configuration) => Configuration = configuration;
    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        //
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseDeveloperExceptionPage();
        app.UseStatusCodePages();
        app.UseStaticFiles();
        app.UseSession();
        app.UseMvc(routes =>
        {
            //
        });

        SeedData.EnsurePopulated(app);
    }
}

Работа класса SeedData заключается в добавлении исходных данных в таблицу базы данных. Это код:

public static void EnsurePopulated(IApplicationBuilder app)
    {
        ApplicationDbContext context = app.ApplicationServices.GetRequiredService<ApplicationDbContext>();
        context.Database.Migrate();
        if (!context.Products.Any())
        {
            context.Products.AddRange(
            new Product
            {
                Name = "Kayak",
                Description = "A boat for one person",
                Category = "Watersports",
                Price = 275
            },
            ....
            );
            context.SaveChanges();
        }
    }

РЕШЕНИЕ

Перед выполнением миграции просто закомментируйте вызов класса SeedData в файле Startup.cs.

// SeedData.EnsurePopulated(app);

Это решило мою проблему, и надеюсь, что ваша проблема также будет решена таким же образом.

Ответ 15

От

https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/dbcontext-creation

Когда вы создаете новое приложение ASP.NET Core 2.0, эта ловушка включается по умолчанию. В предыдущих версиях EF Core и ASP.NET Core инструменты пытались вызвать Startup.ConfigureServices напрямую, чтобы получить поставщика услуг приложения, но этот шаблон больше не работает правильно в приложениях ASP.NET Core 2.0. Если вы обновляете приложение ASP.NET Core 1.x до версии 2.0, вы можете изменить свой класс Program, следуя новому шаблону.

Добавить фабрику в .Net Core 2.x

public class BloggingContextFactory : IDesignTimeDbContextFactory<BloggingContext>
    {
        public BloggingContext CreateDbContext(string[] args)
        {
            var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>();
            optionsBuilder.UseSqlite("Data Source=blog.db");

            return new BloggingContext(optionsBuilder.Options);
        }
    }

Ответ 16

Я столкнулся с той же проблемой. У меня есть два проекта в решении. который

  1. API
  2. Услуги и репо, которые содержат контекстные модели

Изначально проект API был задан как проект запуска.

Я изменил проект автозагрузки на тот, который содержит классы контекста. Если вы используете Visual Studio, вы можете установить проект в качестве проекта запуска:

открыть обозреватель решений >> щелкните правой кнопкой мыши по контекстному проекту >> выберите "Установить как стартовый проект"

Ответ 17

Я получил ту же проблему, так как я имел в виду old- Microsoft.EntityFrameworkCore.Tools.DotNet

<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.0" />

После обновления до новой версии это было решено

Ответ 18

В основном файле appsettings.json проекта я установил "Копировать в выходной каталог" в "Копировать всегда", и это сработало.

Ответ 19

Пример класса контекста БД для основных консольных приложений .net

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration;
using System.IO;

namespace EmailServerConsole.Data
{
    public class EmailDBContext : DbContext
    {
        public EmailDBContext(DbContextOptions<EmailDBContext> options) : base(options) { }
        public DbSet<EmailQueue> EmailsQueue { get; set; }
    }

    public class ApplicationContextDbFactory : IDesignTimeDbContextFactory<EmailDBContext>
    {
        EmailDBContext IDesignTimeDbContextFactory<EmailDBContext>.CreateDbContext(string[] args)
        {
            IConfigurationRoot configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json")
                .Build();
            var builder = new DbContextOptionsBuilder<EmailDBContext>();
            var connectionString = configuration.GetConnectionString("connection_string");
            builder.UseSqlServer(connectionString);
            return new EmailDBContext(builder.Options);
        }
    }
}

Ответ 20

Вы также можете использовать в конструкторе класса запуска, чтобы добавить файл json (где находится строка подключения) в конфигурацию. Пример:

    IConfigurationRoot _config;
    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json");

        _config = builder.Build();
    }

Ответ 21

Для меня это было потому, что я изменил Output Type моего запускаемого проекта с Console Application на Class Library.

Возврат к Console Application сделал свое дело.

Ответ 22

У меня была эта проблема в решении, которое имеет:

  • проект .NET Core 2.2 MVC
  • проект .NET Core 3.0 Blazor
  • Контекст БД в проекте библиотеки классов .NET Standard 2.0

Я получаю сообщение "неспособен создать объект...", когда проект Blazor задан как начальный проект, но не, если проект MVC задан как начальный проект.

Это меня озадачивает, потому что в консоли диспетчера пакетов (именно там я и создаю миграцию) у меня в проекте по умолчанию установлена библиотека классов С#, которая фактически содержит контекст БД, и я также указываю контекст БД в Мой призыв добавить-миграцию add-migration MigrationName -context ContextName, поэтому кажется странным, что Visual Studio заботится о том, какой стартовый проект установлен в данный момент.

Я предполагаю, что причина в том, что когда проект Blazor является проектом запуска, PMC определяет версию .NET для ядра 3.0 из запускаемого проекта, а затем пытается использовать ее для запуска миграций в классе .NET Standard 2.0. библиотека и попадание в какой-то конфликт.

Вне зависимости от причины, изменение стартового проекта на проект MVC, предназначенный для Core 2.2, а не для проекта Blazor, устранило проблему.

Ответ 23

У меня есть проект с многослойной архитектурой. Я забыл, что для моего проекта запуска (Web) задан проект по умолчанию.

Я изменил свой проект по умолчанию на веб (точка входа в проект) и решил проблему

Это мое изображение слоев проекта

Ответ 24

Прежде всего убедитесь, что вы настроили свою базу данных в Startup.cs В моем случае я получал эту ошибку, так как я не указал ниже в Startup.cs

    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection"), x => x.MigrationsAssembly("<Your Project Assembly name where DBContext class resides>")));

Ответ 25

Для меня проблема заключалась в том, что я выполнял команды миграции внутри не того проекта. Выполнение команд внутри проекта, который содержал Startup.cs, а не проекта, который содержал DbContext, позволил мне преодолеть эту конкретную проблему.

Ответ 26

В моем случае эта ошибка произошла из-за того, что я удаляю MyDbContext из ConfigureServices из-за некоторых шаблонов проектирования. Проверь это. В Startup.cs => ConfigureServices добавьте эти строки:

var connectionString = "Application Connection String!!!";
services.AddDbContext<MyDbContext>(c => c.UseSqlServer(connectionString));

Ответ 27

У меня была такая же проблема. Просто изменил ap.jason на application.jason, и это решило проблему