¿Cómo define DBContext correctamente en un proyecto de biblioteca de clases?

asp.net-web-api c# entity-framework entity-framework-core

Pregunta

Estoy usando Entity Framework 7 y creé dos proyectos. Un proyecto como un proyecto de API web ASP.NET 5 y el otro es un Proyecto de biblioteca de clases (paquete) en el que quería almacenar toda la lógica de la capa de acceso a datos. De esta manera puedo usar este paquete para otro proyecto de informes en el futuro y Otros servicios adicionales que pueda hacer.

Básicamente tengo una publicación simple en mi controlador del proyecto de API web que llama a una función en mi proyecto de biblioteca de datos. Cuando la función inicia la base de datos, dice que la base de datos no está definida, aunque esté definida en ambos proyectos.


ERROR

{"No database providers are configured. Configure a database provider by overriding OnConfiguring in your DbContext class or in the AddDbContext method when setting up services."}

CÓDIGO

Proyecto de biblioteca de datos: InsertPerson

{"No database providers are configured. Configure a database provider by overriding OnConfiguring in your DbContext class or in the AddDbContext method when setting up services."}

ARCHIVOS DE CONFIGURACIÓN

Proyecto API web: Startup.cs

{"No database providers are configured. Configure a database provider by overriding OnConfiguring in your DbContext class or in the AddDbContext method when setting up services."}

Proyecto API web: appsettings.json

{"No database providers are configured. Configure a database provider by overriding OnConfiguring in your DbContext class or in the AddDbContext method when setting up services."}

Proyecto API web: project.json

{"No database providers are configured. Configure a database provider by overriding OnConfiguring in your DbContext class or in the AddDbContext method when setting up services."}

Proyecto de biblioteca de datos: Startup.cs

{"No database providers are configured. Configure a database provider by overriding OnConfiguring in your DbContext class or in the AddDbContext method when setting up services."}

Proyecto de biblioteca de datos: appsettings.json

{"No database providers are configured. Configure a database provider by overriding OnConfiguring in your DbContext class or in the AddDbContext method when setting up services."}

Proyecto de biblioteca de datos: AppContext.cs

{"No database providers are configured. Configure a database provider by overriding OnConfiguring in your DbContext class or in the AddDbContext method when setting up services."}

Respuesta aceptada

Parece que su problema en el código de ejemplo es que está actualizando la instancia de AppContext en lugar de resolverla desde el Proveedor de servicios. Cuando inicializa un DbContext de esta manera, se crea implícitamente un nuevo ServiceProvider para el contexto y ese contexto no respeta ninguna de la configuración en Startup.cs. Este es un patrón que desearía utilizar si configurara su contexto en OnConfiguring y no estuviera interesado en la inyección de dependencia en el resto de su aplicación.

En este tipo de situación, esperaría que obtuviera AppContext a través de la inyección del constructor. Para este tipo de solución, también necesitaría registrar sus clases de Capa de acceso a datos en ServiceCollection. El resultado debería verse un poco más como esto:

Proyecto de biblioteca de datos: AppContext.cs

namespace DataLibrary
{
    public class AppContext : IdentityDbContext<ApplicationUser>
    {
        public DbSet<tbl_Person> tbl_Person { get; set; }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            new tbl_PersonMap(builder.Entity<tbl_Person>());
            base.OnModelCreating(builder);
        }
    }
}

Proyecto de biblioteca de datos: PersonHelper.cs

namespace DataLibrary
{
    public class AppContext : IdentityDbContext<ApplicationUser>
    {
        public DbSet<tbl_Person> tbl_Person { get; set; }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            new tbl_PersonMap(builder.Entity<tbl_Person>());
            base.OnModelCreating(builder);
        }
    }
}

Proyecto API web: Startup.cs

namespace DataLibrary
{
    public class AppContext : IdentityDbContext<ApplicationUser>
    {
        public DbSet<tbl_Person> tbl_Person { get; set; }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            new tbl_PersonMap(builder.Entity<tbl_Person>());
            base.OnModelCreating(builder);
        }
    }
}

Proyecto API web: MyController.cs

namespace DataLibrary
{
    public class AppContext : IdentityDbContext<ApplicationUser>
    {
        public DbSet<tbl_Person> tbl_Person { get; set; }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            new tbl_PersonMap(builder.Entity<tbl_Person>());
            base.OnModelCreating(builder);
        }
    }
}

incluso puede considerar agregar un método de extensión en IServiceCollection para sus clases de Capa de acceso a datos para ayudar a reducir la duplicación en su configuración, especialmente a medida que agrega servicios más comunes.


Respuesta popular

Encontré una forma de hacer esto, pero todavía no estoy convencido de que esta sea la mejor manera. En el archivo de clase que contiene mi función de inserción, agregué esto para que cuando se llame desde el proyecto web api, el appcontext de la web api se pase al proyecto de la biblioteca de datos. Dicho esto, no estoy seguro de si hay un enfoque más elegante

public class fnCommon
{
    private readonly AppContext db;

    public fnCommon(AppContext context)
    {
        this.db = context;
    }

    public int InsertPerson(tbl_Person person)
    {

        try
        {
            db.tbl_Person.Add(person);
            db.SaveChanges();
            return person.PersonID;
        }

        catch
        {
            return 0;
        }
    }
}



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué