0

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

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Should I inject CRUDService to controller to perform database operations? After changes you suggest I have lots of errors in controllers. I already set db context as private prop in controller. However context doesn't have all methods from CRUD like ReadAsync(long id, params string[] includes)
Yeah, you need to inject the service using dependency injection (see the DI topic in the documentation). If you need utility methods on a DbSet, you can always create an extension method. The point with using the EF context directly though is that you can create more explicit queries and do not need to load data you don’t actually need just because the repository only offers one way.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.