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

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

Я получаю

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

а также

«Невозможно создать объект типа« 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"

Это моя программа.

  public class Program { public static void Main(string[] args) { BuildWebHost(args).Run(); } public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup() .Build(); } 

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

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

 public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory { public CodingBlastDbContext CreateDbContext(string[] args) { IConfigurationRoot configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json") .Build(); var builder = new DbContextOptionsBuilder(); 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. 

ресурс

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

  

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

 public static IWebHost MigrateDatabase(this IWebHost webHost) { using (var scope = webHost.Services.CreateScope()) { var services = scope.ServiceProvider; try { var db = services.GetRequiredService(); db.Database.Migrate(); } catch (Exception ex) { var logger = services.GetRequiredService>(); logger.LogError(ex, "An error occurred while migrating the database."); } } return webHost; } public static void Main(string[] args) { BuildWebHost(args) .MigrateDatabase() .Run(); } 

В AppContext.cs помимо classа AppContext добавить еще один class:

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

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

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

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

произошел при вызове метода «BuildWebHost» в classе «Программа» … Ошибка входа в систему. Ошибка входа для пользователя «…»

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

Что-то, что действительно помогло мне, было в этой статье: 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 ».

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

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

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

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

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

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

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

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

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

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

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

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

 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); } } 

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

 public static void EnsurePopulated(IApplicationBuilder app) { ApplicationDbContext context = app.ApplicationServices.GetRequiredService(); 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(); } } 

РЕШЕНИЕ

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

 // SeedData.EnsurePopulated(app); 

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

Раньше вы настраивали исходные данные в методе 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(); DbInitializer.Initialize(context); } catch (Exception ex) { var logger = services.GetRequiredService>(); logger.LogError(ex, "An error occurred while seeding the database."); } } host.Run(); } 

У меня такая же проблема, поскольку я ссылался на old-Microsoft.EntityFrameworkCore.Tools.DotNet

  

После перехода на новую версию он был разрешен

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

Из

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, вы можете изменить свой class программы, чтобы следовать новому шаблону.

Добавить Factory в .Net Core 2.x

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

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

 var connectionString = "Application Connection String!!!"; services.AddDbContext(c => c.UseSqlServer(connectionString)); 
Давайте будем гением компьютера.