ProgramingTip

ASP.NET Core 2.0으로 업그레이드 한 후 마이그레이션을 만들 수 없습니다.

bestdevel 2020. 10. 4. 12:02
반응형

ASP.NET Core 2.0으로 업그레이드 한 후 마이그레이션을 만들 수 없습니다.


ASP.NET Core 2.0으로 업그레이드 한 후 더 이상 만들 수없는 것입니다.

나는 강화있다

" 'Program'클래스에서 '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();
}

웹 프로젝트 내부에 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.

자원


에 대한 필요가 없습니다 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'.

제 경우 문제의 원인은 여러 개의 개의 시작 프로젝트였습니다. 내 솔루션에는 Mvc, Api 및 Dal의 세 가지 프로젝트가 있습니다. Dal 프로젝트의 DbContext 및 마이그레이션.

여러 시작 프로젝트를 구성했습니다. Mvc와 Api 프로젝트가 모두 실행 중이었다. 그러나이 경우에는 오류가 발생했습니다.

" 'MyContext'유형의 개체를 만들 수 없습니다. 'IDesignTimeDbContextFactory'을 프로젝트 구현 에 추가 하거나 디자인 타임에 지원되는 추가 패턴에 대해서는 https://go.microsoft.com/fwlink/?linkid=851728참조 하십시오 . "

Mvc를 유일한 시작 프로젝트로 설정하고 패키지 관리자 콘솔에서 Dal을 선택 후 추가 할 수 있습니다.


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().


더 나은 솔루션 :

시작 프로젝트가 ASP.NET Core앱인 경우 도구 DbContext는 애플리케이션의 서비스 공급자로부터 개체 를 가져 오려고합니다 .

도구는 먼저 속성 을 호출 Program.BuildWebHost()하고 액세스하여 서비스 공급자를 가져 오려고 IWebHost.Services합니다.

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

다른 가능한 해결책 :

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 코드 :

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

}

업데이트 : 웹 응용 프로그램 프로젝트를 "시작 프로젝트로 설정"으로 설정

Visual Studio의 메뉴 Tools-> NuGet Package Manger-> Package Manager Console에서 패키지 관리자 콘솔을 다음 명령을 실행합니다.

Add-Migration Init -Verbose

참고 :이 –verbose옵션을 사용 하여 대상 데이터베이스에 적용되는 SQL 문을 확인합니다. 자세한 오류가 있습니다.


AppContext 클래스 외에 AppContext.cs에서 다른 클래스를 추가하십시오.

// 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'구현을 프로젝트에 추가합니다.

후에 그 마이그레이션 초기

추가 하고 갱신 데이터베이스 명령 을 실행하여 실행할 수 있습니다. 그러나 로컬 SqlServer에 아직 데이터베이스가 없을 때 명령을 실행하면 첫 번째 오류와 같은 경고가 표시됩니다. "오류

'프로그램'클래스에서 'BuildWebHost'메서드를 호출하는 동안 발생했습니다 ... 로그인에 실패했습니다. 사용자 '...'에 대한 로그인 실패 "

그러나 마이그레이션이 생성되고 실행될 수 있기 때문에 오류가 아닙니다. Db가 처음 으로이 오류를 무시하고 Db가 사용 후자는 다시 발생하지 않습니다.


참조가 있는지 확인하십시오

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

저에게 보내는 도움이 된 것은 사실이었다 : 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 작업은 작업을 수행 할 때 DB 초기화를 시도하고 실행합니다.

"공식 초기화 마이그레이션 문서 ( https://docs.microsoft.com/en-us/ef/core/miscellaneous/1x-2x-upgrade )에"데이터베이스 코드 이동 "이라는 멋진 섹션 이 있습니다. 그리워했습니다. 그래서 제가 한 것처럼 토끼 구멍을 뚫기 전에 IdesignTimeDbContextFactory 구현을 추가해야하는 원인이 아닌지 확인하십시오. "


이 게시물 에서 영감 얻은 이 토론 에서이 솔루션을 시도 할 수 있습니다 .

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

이 문제가 있지만 Set-> Web Application (Included Program.cs) Project에서-> "Set as Startup Project"로이 문제가 해결되었습니다.

그런 다음-> add-migration initial -verbose를 실행하십시오.

패키지 관리자 콘솔에서

시작 프로젝트로 설정


그래야 IDesignTimeDbContextFactory를 피 결제 시작시 Seed 메소드를 사용하지 않는지 확인하십시오. 내 시작에서 정적 시드 방법을 사용하고 있었는데 이로 인해 오류가 발생했습니다.


이전에는 Startup.cs의 Configure 메서드에서 시드 데이터를 구성했습니다. 이제 요청 파이프 라인을 설정하는 데만 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();
}


2.0의 Startup.Configure에서 ef seeding db에 문제가 있습니다 ...이 해결 방법은 여전히 ​​할 수 있습니다. 테스트를 잘 작동했습니다.

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


제 경우에는 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);
    }
}

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

해결책

마이그레이션을 수행하기 전에 Startup.cs 파일에서 SeedData 클래스 호출을 주석으로 처리 합니다.

// SeedData.EnsurePopulated(app);

그것은 내 문제를 해결하고 당신의 문제도 같은 방식으로 해결되기를 바랍니다.


에서

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

나는 같은 문제에 부딪쳤다. 솔루션에 두 개의 프로젝트가 있습니다. 어느

  1. API
  2. 컨텍스트 모델을 보유하는 서비스 및 저장소

처음에는 API 프로젝트가 시작 프로젝트로 설정되었습니다.

Startup 프로젝트를 컨텍스트 클래스를 보유하는 프로젝트로 변경했습니다 . Visual Studio사용하는 경우 다음을 수행하여 프로젝트를 시작 프로젝트로 설정할 수 있습니다.

솔루션 탐색기 열기 >> 컨텍스트 프로젝트를 마우스 오른쪽 버튼으로 클릭 >> 시작 프로젝트로 설정 선택


이전 Microsoft.EntityFrameworkCore.Tools.DotNet을 참조했기 때문에 동일한 문제가 발생했습니다.

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

최신 버전으로 업그레이드 한 후 문제가 해결되었습니다.


메인 프로젝트의 appsettings.json 파일에서 'Copy to Output directory'를 "Copy always"로 설정했고 제대로 작동했습니다.


.net 핵심 콘솔 애플리케이션 용 샘플 DB 컨텍스트 클래스

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

시작 클래스 생성자에서 사용하여 구성에 json 파일 (연결 문자열이있는 위치)을 추가 할 수도 있습니다. 예:

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

        _config = builder.Build();
    }

I가 변경 되었기 때문에 나에게는이었다 Output Type에서 내 시작 프로젝트의를 Console ApplicationClass Library.

로 되돌려 Console Application트릭을 수행했습니다.


다음과 같은 솔루션에서이 문제가 발생했습니다.

  • .NET Core 2.2 MVC 프로젝트
  • .NET Core 3.0 Blazor 프로젝트
  • .NET Standard 2.0 클래스 라이브러리 프로젝트의 DB 컨텍스트

Blazor 프로젝트를 시작 프로젝트로 설정하면 "개체를 만들 수 없습니다 ..."라는 메시지가 표시되지만 MVC 프로젝트가 시작 프로젝트로 설정된 경우에는 표시되지 않습니다.

패키지 관리자 콘솔 (마이그레이션을 생성하는 곳)에서 기본 프로젝트가 실제로 DB 컨텍스트를 포함하는 C # 클래스 라이브러리로 설정되어 있고 DB 컨텍스트도 add-migration에 대한 호출 add-migration MigrationName -context ContextName이므로 Visual Studio가 현재 설정된 시작 프로젝트에 관심이 있다는 것이 이상하게 보입니다.

그 이유는 Blazor 프로젝트가 시작 프로젝트 일 때 PMC가 시작 프로젝트에서 .NET 버전을 Core 3.0으로 결정한 다음이를 사용하여 .NET Standard 2.0 클래스에서 마이그레이션을 실행하려고하기 때문이라고 생각합니다. 도서관과 일종의 충돌을 일으키고 있습니다.

원인이 무엇이든 시작 프로젝트를 Blazor 프로젝트가 아닌 Core 2.2를 대상으로하는 MVC 프로젝트로 변경하면 문제가 해결되었습니다.


우선 데이터베이스를 구성했는지 확인하십시오 Startup.cs. 제 경우에는 아래를 지정하지 않았 으므로이 오류가 발생했습니다.Startup.cs

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

나는 같은 문제가 있었다. ap.jason을 application.jason로 변경하고 문제를 해결했습니다.

참고 URL : https://stackoverflow.com/questions/45782446/unable-to-create-migrations-after-upgrading-to-asp-net-core-2-0

반응형