# Layered Solution: Database configurations ```json //[doc-nav] { "Previous": { "Name": "Authentication", "Path": "solution-templates/layered-web-application/authentication" }, "Next": { "Name": "Logging (with Serilog)", "Path": "solution-templates/layered-web-application/logging" } } ``` > Some of the features mentioned in this document may not be available in the free version. We're using the **\*** symbol to indicate that a feature is available in the **[Team](https://abp.io/pricing)** and **[Higher](https://abp.io/pricing)** licenses. ABP Studio's Layered Solution Template includes pre-configured database settings. This document explains how to manage database configurations in your solution. ## Connection Strings Connection strings are stored in the `appsettings.json` file. You can customize them for different environments by modifying the respective `appsettings.json` files. The `*.DbMigrator` project and one of the [Web Application](web-applications.md) projects use the `Default` connection string by default. To change the connection string for the `Default` key, update the `appsettings.json` file in your project. Connection strings are defined under the `ConnectionStrings` section, as shown below: ```json { "ConnectionStrings": { "Default": "Server=(LocalDb)\\MSSQLLocalDB;Database=Bookstore;Trusted_Connection=True;TrustServerCertificate=true" } } ``` ### The DbContext Class In the `*.EntityFrameworkCore` project, the `DbContext` class is defined. The `DbContext` class is derived from the `AbpDbContext` class, which is a part of the ABP Framework. ```csharp [ReplaceDbContext(typeof(IIdentityProDbContext))] [ReplaceDbContext(typeof(ISaasDbContext))] [ConnectionStringName("Default")] public class BookstoreDbContext : AbpDbContext, ISaasDbContext, IIdentityProDbContext { #region Entities from the modules // Identity public DbSet Users { get; set; } public DbSet Roles { get; set; } public DbSet ClaimTypes { get; set; } public DbSet OrganizationUnits { get; set; } public DbSet SecurityLogs { get; set; } public DbSet LinkUsers { get; set; } public DbSet UserDelegations { get; set; } public DbSet Sessions { get; set; } // SaaS public DbSet Tenants { get; set; } public DbSet Editions { get; set; } public DbSet TenantConnectionStrings { get; set; } #endregion public BookstoreDbContext(DbContextOptions options) : base(options) { } protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); builder.ConfigurePermissionManagement(); builder.ConfigureSettingManagement(); builder.ConfigureBackgroundJobs(); builder.ConfigureAuditLogging(); builder.ConfigureFeatureManagement(); builder.ConfigureIdentityPro(); builder.ConfigureOpenIddictPro(); builder.ConfigureLanguageManagement(); builder.ConfigureSaas(); builder.ConfigureTextTemplateManagement(); builder.ConfigureGdpr(); builder.ConfigureCmsKit(); builder.ConfigureCmsKitPro(); builder.ConfigureBlobStoring(); /* Configure your own tables/entities inside here */ //builder.Entity(b => //{ // b.ToTable(BookstoreConsts.DbTablePrefix + "YourEntities", BookstoreConsts.DbSchema); // b.ConfigureByConvention(); //auto configure for the base class props // //... //}); } } ``` #### ConnectionStringName Attribute We're using the *Default* connection string in the `BookstoreDbContext` class. You can change the connection string name by updating the `ConnectionStringName` attribute. ```csharp [ConnectionStringName("Default")] ``` [The `ConnectionStringName` attribute](../../framework/fundamentals/connection-strings.md#set-the-connection-string-name) defines the unique name of the connection string that is being used by that `DbContext` class. It matches with the connection string defined in the `appsettings.json` file. That name is also used in database migrations to distinguish different database schemas, and used as the key while storing tenant connection strings for a multi-tenant system. #### ReplaceDbContext Attribute ```csharp [ReplaceDbContext(typeof(IIdentityProDbContext))] [ReplaceDbContext(typeof(ISaasDbContext))] ``` The application DbContext utilizes the [Identity](../../modules/identity.md) and [Saas **\***](../../modules/saas.md) modules and creates a single database that contains these modules database schemas. These modules define their own `DbContext` class normally. But [the `ReplaceDbContext` attribute](../../framework/data/entity-framework-core/index.md#replace-other-dbcontextes) tells to ABP to use this (`BookstoreDbContext`) `DbContext` class instead of the `DbContext` classes defined by these modules. Technically, it replaces the given `DbContext` classes on runtime. We are doing that to ensure that we have a single (merged) database schema, single database migration path and a single database transaction operation when we work these multiple modules. When we replace a `DbContext`, we should implement its interface as done with the `BookstoreDbContext` class: ````csharp public class BookstoreDbContext : AbpDbContext, ISaasDbContext, IIdentityProDbContext ```` * That class implements `ISaasDbContext` and `IIdentityProDbContext`, so these modules can use it. As the next part, the `BookstoreDbContext` class defines the following properties those are forced by the implemented interfaces: ```csharp // Identity public DbSet Users { get; set; } public DbSet Roles { get; set; } public DbSet ClaimTypes { get; set; } public DbSet OrganizationUnits { get; set; } public DbSet SecurityLogs { get; set; } public DbSet LinkUsers { get; set; } public DbSet UserDelegations { get; set; } public DbSet Sessions { get; set; } // SaaS public DbSet Tenants { get; set; } public DbSet Editions { get; set; } public DbSet TenantConnectionStrings { get; set; } ``` #### OnModelCreating Method The `OnModelCreating` method is used to configure the database schema. It calls the `Configure*` methods of the ABP Framework to configure the database schema for the modules. You can also configure your own tables/entities inside this method. ```csharp protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); builder.ConfigurePermissionManagement(); builder.ConfigureSettingManagement(); builder.ConfigureBackgroundJobs(); builder.ConfigureAuditLogging(); builder.ConfigureFeatureManagement(); builder.ConfigureIdentityPro(); builder.ConfigureOpenIddictPro(); builder.ConfigureLanguageManagement(); builder.ConfigureSaas(); builder.ConfigureTextTemplateManagement(); builder.ConfigureGdpr(); builder.ConfigureCmsKit(); builder.ConfigureCmsKitPro(); builder.ConfigureBlobStoring(); /* Configure your own tables/entities inside here */ //builder.Entity(b => //{ // b.ToTable(BookstoreConsts.DbTablePrefix + "YourEntities", BookstoreConsts.DbSchema); // b.ConfigureByConvention(); //auto configure for the base class props // //... //}); } ``` > The `Configure*` methods are extension methods defined in each module's `EntityFrameworkCore` project. These methods are used to configure the database schema for their respective modules. At runtime, the `DbContext` class is replaced by the `BookstoreDbContext` class only for the `DbContext` classes that use the `ReplaceDbContext` attribute. For other modules, their own dedicated `DbContext` classes are used without replacement. ### The `IDesignTimeDbContextFactory` Implementation The `IDesignTimeDbContextFactory` interface is used to create a `DbContext` instance at design time. It is used by EF Core tools to create migrations and update the database. The `BookstoreDbContextFactory` class implements the `IDesignTimeDbContextFactory` interface to create a `BookstoreMigrationsDbContext` instance. ```csharp public class BookstoreDbContextFactory : IDesignTimeDbContextFactory { public BookstoreDbContext CreateDbContext(string[] args) { var configuration = BuildConfiguration(); BookstoreEfCoreEntityExtensionMappings.Configure(); var builder = new DbContextOptionsBuilder() .UseSqlServer(configuration.GetConnectionString("Default")); return new BookstoreDbContext(builder.Options); } private static IConfigurationRoot BuildConfiguration() { var builder = new ConfigurationBuilder() .SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), "../Acme.Bookstore.DbMigrator/")) .AddJsonFile("appsettings.json", optional: false); return builder.Build(); } } ``` ### Configuration In the `*.EntityFrameworkCore` project, the `BookstoreEntityFrameworkCoreModule` class is used to configure the database context. ```csharp public override void ConfigureServices(ServiceConfigurationContext context) { context.Services.AddAbpDbContext(options => { /* Remove "includeAllEntities: true" to create * default repositories only for aggregate roots */ options.AddDefaultRepositories(includeAllEntities: true); }); Configure(options => { /* The main point to change your DBMS. * See also BookstoreDbContextFactory for EF Core tooling. */ options.UseSqlServer(); }); } ``` We are basically setting the SQL Server as the default DBMS for this application. and registering the `BookstoreDbContext` class to the [dependency injection](../../framework/fundamentals/dependency-injection.md) system.