Search code examples
entity-framework-coredbcontextmultiple-databases.net-7.0

Creating Repository Pattern that provides multiple DbContexts with Entity Framework in .Net Core Web API


I want to develop a structure that will support generic DbContexts in the .Net Core Web API project and can be used in the repository pattern. Mysql and PostreSql databases are sufficient for now. Can you help with this?


Solution

    1. Create a new .Net Core Web API project.

    2. Add a new folder in the project called DataAccess and create a new class called BaseDbContext that inherits from DbContext. This class will contain the common properties and methods for all your DbContexts.

        public class BaseDbContext : DbContext
            {
                public BaseDbContext(DbContextOptions options) : base(options) { }
                //...
            }
    
    1. Create a new class called MySqlDbContext that inherits from BaseDbContext. This class will contain the properties and methods specific to the MySQL database.
        public class MySqlDbContext : BaseDbContext
        {
            public MySqlDbContext(DbContextOptions<MySqlDbContext> options) : base(options) { }
            //...
        }
    
    1. Create a new class called PostgreSqlDbContext that inherits from BaseDbContext. This class will contain the properties and methods specific to the PostgreSQL database.
        public class PostgreSqlDbContext : BaseDbContext
        {
            public PostgreSqlDbContext(DbContextOptions<PostgreSqlDbContext> options) : 
        base(options) { }
            //...
        }
    
    
    1. Create a new folder in the project called Repositories and create a new class called BaseRepository that will contain the common methods for all your repositories.
    public class BaseRepository<T> where T : class
    {
        protected readonly DbContext _context;
    
        public BaseRepository(DbContext context)
        {
            _context = context;
        }
    
        //...
    }
    
    
    1. Create new classes for each repository that inherits from BaseRepository and pass the appropriate DbContext to the base constructor.
    public class MySqlRepository : BaseRepository<MySqlDbContext>
    {
        public MySqlRepository(MySqlDbContext context) : base(context) { }
        //...
    }
    

    and

    
    public class PostgreSqlRepository : BaseRepository<PostgreSqlDbContext>
    {
        public PostgreSqlRepository(PostgreSqlDbContext context) : base(context) { }
        //...
    }
    
    

    In your controllers you can now inject the appropriate repository and use it to interact with the database.

    You can also use dependency injection to inject the appropriate DbContext based on the configuration.

    Additional:

    Here is an example of how you can do this:

    1. In your appsettings.json file, add a section for the database connection information, such as:
    {
      "ConnectionStrings": {
        "MySqlConnection": "Server=localhost;Database=mydb;User=user;Password=password;",
        "PostgreSqlConnection": "Host=localhost;Database=mydb;Username=user;Password=password;"
      },
      "DatabaseProvider": "MySql"
    }
    

    Here the DatabaseProvider field indicate the database that user wants to use. 2. In your Startup.cs file, create a new method called ConfigureDbContext that will configure the DbContext based on the configuration in the appsettings file

    public void ConfigureDbContext(IServiceCollection services)
    {
        var connectionString = Configuration.GetConnectionString("MySqlConnection");
        var provider = Configuration.GetValue<string>("DatabaseProvider");
        if(provider == "MySql")
        {
            services.AddDbContext<MySqlDbContext>(options => options.UseMySql(connectionString));
        }
        else if (provider == "PostgreSql")
        {
            services.AddDbContext<PostgreSqlDbContext>(options => options.UseNpgsql(connectionString));
        }
    }
    
    1. In the ConfigureServices method in Startup.cs, call the ConfigureDbContext method to configure the DbContext.
    public void ConfigureServices(IServiceCollection services)
    {
        ConfigureDbContext(services);
        //...
    }
    
    1. In your controllers, you can now inject the appropriate DbContext using dependency injection.
    public class MyController : Controller
    {
        private readonly IDbContext _context;
    
        public MyController(IDbContext context)
        {
            _context = context;
        }
        //...
    }