it-roy-ru.com

Невозможно создать миграции после обновления до 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();
}
49
ruhm

Вы можете добавить класс, который реализует 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.

ресурс

65
jaaso

Нет необходимости для 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'.
16
tchelidze

В 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 command . Однако, если вы выполните эти команды, когда в вашем локальном SqlServer еще нет базы данных, вы получите предупреждение, как ваша первая ошибка: «ошибка

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

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

4
borisdj

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

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

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

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

3
Gürol Mehmet Cetin

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

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();
}
3
user2771704

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

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

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

3
Rtype

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

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

В моем случае я получил проблему, потому что у меня был метод 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);

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

2
yogihosting

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

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

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

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

2
Miguel Torres C

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

2
codeYouLaterBro

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

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

2
Nick G.

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

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

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

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

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

От

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

Добавить фабрику в .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);
        }
    }
2
Anton Swanevelder

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

Затем запустите -> add -igration initial -verbose 

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

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

1
Ali Ahmadi
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, потому что миграция использует этот метод по умолчанию

0
sherox

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

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

        _config = builder.Build();
    }
0
Vio

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

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

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

0
vinayak hegde

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

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

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

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

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

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

0
tomRedox

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

0
AliAzra

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

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

0
Robouste

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

0
geet

Пример класса контекста БД для основных консольных приложений .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);
        }
    }
}
0
Isanka Thalagala