Не удалось создать миграции после обновления до 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:
Установите для проекта веб-приложения значение "Установить как стартовый проект"
Откройте консоль диспетчера пакетов из меню Tools
→ NuGet Package Manger
→ Package 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
Я столкнулся с той же проблемой. У меня есть два проекта в решении. который
- API
- Услуги и репо, которые содержат контекстные модели
Изначально проект 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, и это решило проблему