c# - No se pueden crear migraciones después de actualizar a ASP.NET Core 2.0




asp.net-core asp.net-core-mvc (16)

Después de actualizar a ASP.NET Core 2.0, parece que ya no puedo crear migraciones.

Me estoy poniendo

"Se produjo un error al llamar al método 'BuildWebHost' en la clase 'Programa'. Continuar sin el proveedor de servicios de aplicaciones. Error: Se produjeron uno o más errores. (No se puede abrir la base de datos" ... "solicitada por el inicio de sesión. El inicio de sesión falló. Iniciar sesión falló para el usuario '...' "

y

"No se puede crear un objeto de tipo 'MyContext'. Agregue una implementación de 'IDesignTimeDbContextFactory' al proyecto, o consulte https://go.microsoft.com/fwlink/?linkid=851728 para obtener patrones adicionales compatibles en el momento del diseño".

El comando que ejecuté anteriormente era $ dotnet ef migrations add InitialCreate --startup-project "..\Web" (desde el proyecto / carpeta con el DBContext).

Cadena de conexión: "Server=(localdb)\\mssqllocaldb;Database=database;Trusted_Connection=True;MultipleActiveResultSets=true"

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

Algo que realmente me ayudó fue este artículo: https://elanderson.net/2017/09/unable-to-create-an-object-of-type-applicationdbcontext-add-an-implementation-of-idesigntimedbcontextfactory/

La idea básica es que en el cambio de .net core 1 a 2, toda la inicialización de db se debe mover de StartUp.cs a Program.cs. De lo contrario, las tareas de EF intentan ejecutar su DB inits al realizar tareas.

"Hay una buena sección en los documentos oficiales de migración ( https://docs.microsoft.com/en-us/ef/core/miscellaneous/1x-2x-upgrade ) titulada" Mover el código de inicialización de la base de datos "que parecía tener errado. Así que antes de que te dirijas a cualquier agujero de conejo como yo me aseguré de que esto no sea lo que está causando tu necesidad de agregar una implementación de IdesignTimeDbContextFactory ".


Anteriormente, configuró los datos semilla en el método Configure en Startup.cs. Ahora se recomienda que utilice el método Configurar solo para configurar la canalización de solicitudes. El código de inicio de la aplicación pertenece al método Main.

El método principal refactorizado. Agregue las siguientes referencias a Program.cs:

usando Microsoft.Extensions.DependencyInjection;

usando MyProject.MyDbContextFolder;

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


Ejemplo de clase de contexto DB para aplicaciones de consola central .net

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

        _config = builder.Build();
    }

En AppContext.cs, además de la clase AppContext, agregue otra clase:

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

Esto resolverá tu segundo problema:

"No se puede crear un objeto de tipo 'MyContext'. Agregue una implementación de 'IDesignTimeDbContextFactory' al proyecto,

Después de eso, podrá agregar la migración inicial y ejecutarla ejecutando el comando update-database . Sin embargo, si ejecuta estos comandos cuando aún no hay DataBase en su SqlServer local, recibirá la advertencia como su primer error: "Un error

ocurrió al llamar al método 'BuildWebHost' en la clase 'Programa' ... El inicio de sesión falló. Error de usuario '...'"

Pero no es un error porque se creará la migración y se puede ejecutar. Así que simplemente ignore este error por primera vez, y después, dado que Db existirá, no volverá a suceder.


En mi caso, este error ocurrió debido a que eliminé MyDbContext de ConfigureServices debido a algunos patrones de diseño. Mira esto. En Startup.cs => ConfigureServices agregue estas líneas:

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

En mi caso, la causa del problema fueron múltiples proyectos de inicio. Tengo tres proyectos en mi solución: Mvc, Api y Dal. DbContext y Migraciones en el proyecto Dal.

Había configurado múltiples proyectos de inicio. Tanto los proyectos Mvc como Api se estaban ejecutando cuando hice clic en Iniciar. Pero en este caso recibí este error.

"No se puede crear un objeto de tipo 'MyContext'. Agregue una implementación de 'IDesignTimeDbContextFactory' al proyecto, o consulte https://go.microsoft.com/fwlink/?linkid=851728 para obtener patrones adicionales compatibles en el momento del diseño".

Pude agregar con éxito la migración después de configurar Mvc como el único proyecto de inicio y seleccionar Dal en la consola de Package Manager.



Me encontré con el mismo problema. Tengo dos proyectos en la solución. cual

  1. API
  2. Servicios y repositorio, que contienen modelos contextuales.

Inicialmente, el proyecto API se estableció como proyecto de inicio.

Cambié el proyecto de inicio al que contiene clases de contexto. Si está utilizando Visual Studio , puede configurar un proyecto como Proyecto de inicio:

Abra el explorador de soluciones >> haga clic con el botón derecho en el proyecto de contexto >> seleccione Establecer como proyecto de inicio


Puede agregar una clase que implemente IDesignTimeDbContextFactory dentro de su proyecto web.

Aquí está el código de ejemplo:

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

Luego, navegue a su proyecto de base de datos y ejecute lo siguiente desde la línea de comandos:

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.

resource


Puede probar esta solución a partir de esta discusión , que se inspiró en esta publicación .

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

Si quieres evitar esa cosa IDesignTimeDbContextFactory: solo asegúrate de no utilizar ningún método de Seed en tu inicio. Estaba usando un método de semilla estática en mi inicio y me estaba causando este error.


También puede usar en el constructor de la clase de inicio para agregar un archivo json (donde se encuentra la cadena de conexión) a la configuración. Ejemplo:

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

Tuve este problema en una solución que tiene:

  • un proyecto .NET Core 2.2 MVC
  • un proyecto .NET Core 3.0 Blazor
  • El contexto DB en un proyecto de biblioteca de clase .NET Standard 2.0

Recibo el mensaje "no se puede crear un objeto ..." cuando el proyecto Blazor se configura como el proyecto de inicio, pero no si el proyecto MVC se configura como el proyecto de inicio.

Eso me desconcierta, porque en la Consola del Administrador de paquetes (que es donde estoy creando la migración) tengo el proyecto predeterminado configurado en una biblioteca de clase C # que realmente contiene el contexto DB, y también estoy especificando el contexto DB en mi llamado a agregar-migración add-migration MigrationName -context ContextName , por lo que parece extraño que a Visual Studio le add-migration MigrationName -context ContextName qué proyecto de inicio está configurado actualmente.

Supongo que la razón es que cuando el proyecto Blazor es el proyecto de inicio, el PMC determina que la versión de .NET sea Core 3.0 del proyecto de inicio y luego intenta usar eso para ejecutar las migraciones en la clase .NET Standard 2.0 biblioteca y golpear un conflicto de algún tipo.

Cualquiera sea la causa, el cambio del proyecto de inicio al proyecto MVC que apunta a Core 2.2, en lugar del proyecto Blazor, solucionó el problema


Tuve este problema y lo resolví por Conjunto -> Proyecto de aplicación web (incluido Program.cs) a -> "Establecer como proyecto de inicio"

Luego ejecute -> add-migración initial -verbose

en la consola de Package Manager

Establecer como proyecto de inicio


por favor verifique que tiene la referencia

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

No es necesario IDesignTimeDbContextFactory .

correr

add-migration initial -verbose

eso revelará los detalles bajo

Se produjo un error al acceder a IWebHost en la clase 'Programa'. Continuando sin el proveedor de servicios de aplicaciones.

advertencia, que es la causa raíz del problema.

En mi caso , el problema era tener ApplicationRole : IdentityRole<int> e invocar services.AddIdentity<ApplicationUser, IdentityRole>() AddIdentity services.AddIdentity<ApplicationUser, IdentityRole>() que estaba causando el siguiente error

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'.




asp.net-core-2.0