Come si definisce correttamente DBContext in un progetto di libreria di classi?

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

Domanda

Sto usando l'entità framework 7 e ho creato due progetti. Un progetto come un progetto di API Web ASP.NET 5 e l'altro è un progetto di libreria di classi (pacchetto) in cui ho voluto memorizzare tutta la mia logica di livello di accesso ai dati. In questo modo posso utilizzare questo pacchetto per un altro progetto di reportistica lungo la strada e altri servizi aggiuntivi che posso fare.

Fondamentalmente ho un post semplice nel mio controller del progetto web api che chiama una funzione nel mio progetto di libreria di dati. Quando la funzione avvia il database, dice che il database non è definito anche se è definito in entrambi i progetti.


ERRORE

{"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."}

CODICE

Progetto Data Library: 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."}

FILE DI CONFIGURAZIONE

Progetto 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."}

Progetto 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."}

Progetto 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."}

Progetto Data Library: 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."}

Progetto Data Library: 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."}

Progetto Data Library: 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."}

Risposta accettata

Sembra che il tuo problema nel codice di esempio sia che stai facendo di nuovo l'istanza di AppContext invece di risolverlo dal ServiceProvider. Quando si inizializza DbContext in questo modo, viene creato implicitamente un nuovo ServiceProvider per il contesto e nessuna configurazione in Startup.cs viene rispettata da quel contesto. Questo è uno schema che vorresti usare se configurassi il tuo contesto in OnConfiguring e non ti interessasse l'integrazione delle dipendenze nel resto della tua applicazione.

In questo tipo di situazione, mi aspetto che tu riceva l'AppContext tramite l'iniezione del costruttore. Per questo tipo di soluzione, è inoltre necessario registrare le classi del livello di accesso ai dati in ServiceCollection. Il risultato dovrebbe essere un po 'più simile a questo:

Progetto Data Library: 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);
        }
    }
}

Progetto Data Library: 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);
        }
    }
}

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

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

si può anche considerare di aggiungere un metodo di estensione su IServiceCollection per le classi di livello di accesso ai dati per ridurre la duplicazione nella configurazione, specialmente quando si aggiungono più servizi comuni.


Risposta popolare

Ho trovato un modo per farlo, ma non sono ancora convinto che questo sia il modo migliore. Nel file di classe che contiene la mia funzione di inserimento, l'ho aggiunto in modo tale che quando viene chiamato dal progetto web api, l'appcontext dal web api venga passato al progetto della libreria di dati. Detto questo, non sono sicuro che ci sia un approccio più 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;
        }
    }
}



Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché