Inhaltsverzeichnis

EF DbContext

ConnectionString vs. AddScope

Die Startup.cs wird so angepasst, dass für DI die Datenbankverbindung als Scope (jeder Aufruf bekommt seine eine Instanz) angelegt wird. Hier wird auch gleich für CodeFirst das DatabaseMigration() ausgeführt.

startup.cs
public void ConfigureServices(IServiceCollection services)
{
    string connectionString = Configuration.GetConnectionString( "YourConnectionString" );
    services.AddScoped<ProductRepository>( scope =>
    {
        var db = new YourRepository( connectionString );
        var isDb = db.DatabaseCreate( );
        db.DatabaseMigration();
        return db;
    });
}

Ich bin für das Repository-Pattern. Hier werden zBsp. Zugriffe auf Datenbankobjekte generell zusammengefasst. Ich greife nicht direkt auf den DbContext bzw. die Enity-Klassen zu. Dies wird im Repository als Wrapper gemacht. Gleichzeitig wird das Repository für den Aufbau/Parematerweitergabe für die Datenbankverbindung genutzt.

YourRepository.cs
class YourRepository
{
    private readonly string _connectionString;
 
    public YourRepository( string connectionString )
    {
        _connectionString = connectionString;
        _context = new Models.YourDbContext( _connectionString );
    }
 
    public bool DatabaseCreate( )
    {
        return _context.Database.EnsureCreated( );
    }
 
    public void DatabaseMigration( )
    {
        _context.Database.Migrate( );
    }
}

Tja: Und der DbContext hat nun zwei Ctor`s. Einer wird für das Ef-Core benutzt und ist per Default mit DbContextOptions aufgerufen. Der zweite Ctor bekommt als Parameter den string der Datenbankverbindung.

YourDbContext.cs
class YourDbContext
{
    private readonly string _connectionString;
 
    internal virtual DbSet<UrDbClass> YourTableClass{ get; set; } //cool, no plublic table access
 
    public YourDbContext(string connectionString) : base()
    {
        _connectionString = connectionString;
    }
 
    public YourDbContext(DbContextOptions<ProductDesignContext> options) //needed for Ef Core reverse .. an so one
        : base(options)
    {
 
    }
 
    //and now.. we pass the connection string in the OnConfigure proc
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
            //#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263.
            //optionsBuilder.UseNpgsql("ConnectionString needed for Ef Core.. and plese dont use hard coded string ;)");
            optionsBuilder.UseNpgsql( _connectionString );
        }
    }
}