简体   繁体   中英

.NET Core 2.x get connection string from appsettings.json in dbcontext class

I have problem with set connection string in my DBContext class. I know I can inject IConfiguration in SqlLiteDbcontext construtor or use IOption pattern but in CRUD.cs I already use parameterless constructor. I'm looking for solution that doesn't require CRUD.cs modification.

    public class SqliteDbContext : DbContext
    {
        public SqliteDbContext() : base()
        {
        }

        public SqliteDbContext(DbContextOptions<SqliteDbContext> options) : base(options)
        {
        }
 protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlite("Data Source=App_Data/sqlite.db");

            optionsBuilder.EnableSensitiveDataLogging(true);
        }

Startup.cs

public void ConfigureServices(IServiceCollection services)
        {
            services.AddAuthentication(IISDefaults.AuthenticationScheme);
            services.AddMemoryCache();
            services.AddMvc();
            // Adds services required for using options.
            //services.AddOptions();

            services.Configure<MvcOptions>(options =>
            {
            });

            services.AddDbContext<SqliteDbContext>(options =>
                options.UseSqlite(Configuration.GetConnectionString("Sqlite")));

CRUD.cs

 public partial class CRUD<T> where T : class, ICreatedDate, IId
    {
        private SqliteDbContext db;
        private DbSet<T> DbSet => db.Set<T>();

        public List<T> Read()
        {
            using (db = new SqliteDbContext())
            {
                return DbSet.ToList();
            }
        }
//...

You should not use Entity Framework like that within ASP.NET Core. You have dependency injection and a properly configured EF context, so you should utilize that. This essentially means:

  1. Never create a database context manually using new . Always inject the context as a dependency.
  2. Don't override the OnConfiguring method in the database to configure the context. Configuration is expected to be passed as DbContextOptions , so that the context itself is not responsible of setting up the configuration.
  3. Avoid an empty constructor for your database context to avoid misuse where the context stays unconfigured.

So your code should look like this:

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

    // define your database sets
    public DbSet<Entity> Entities { get; set; }
}

public class CRUDService<T>
{
    private readonly SqliteDbContext db;
    CRUDService(SqliteDbContext database)
    {
        db = database;
    }

    public List<T> Read()
    {
        return db.Set<T>().ToList();
    }
}

The SqliteDbContext will be automatically provided by the dependency injection container. You just need to inject the dependency for it to be resolved properly.

Btw. I would generally suggest you to avoid a (generic) repository pattern. The database context in Entity Framework is already the unit of work and each database set is already a repository. So you can just use that directly. There is little you gain from adding another abstraction on top of it, especially a generic one, as that will always limit you.

Also, you should rename your SqliteDbContext to something that actually describes what data the context manages. The context should not care about what underlying database provider is being used.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM