using Microsoft.EntityFrameworkCore;
namespace APP.Domain
{
/// <summary>
/// Represents the Entity Framework Core database context for the Products application domain.
/// Manages the entity sets and provides configuration for database access.
/// </summary>
public class Db : DbContext
{
/// <summary>
/// Gets or sets the <see cref="DbSet{TEntity}"/> representing categories in the database.
/// Each <see cref="Category"/> entity corresponds to a record in the Categories table.
/// </summary>
public DbSet<Category> Categories { get; set; }
public DbSet<Store> Stores { get; set; }
public DbSet<Product> Products { get; set; }
public DbSet<ProductStore> ProductStores { get; set; }
public DbSet<Group> Groups { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<User> Users { get; set; }
public DbSet<UserRole> UserRoles { get; set; }
public DbSet<Country> Countries { get; set; }
public DbSet<City> Cities { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="Db"/> class using the specified options.
/// </summary>
/// <param name="options">
/// The options to be used by the <see cref="DbContext"/>, such as the database provider and connection string (from appsettings.json).
/// </param>
public Db(DbContextOptions options) : base(options)
{
}
// Overriding OnModelCreating method is optional.
/// <summary>
/// Configures the entity relationships and database schema rules for the application domain.
/// This method defines how entities are related, sets up foreign key constraints, and customizes
/// the delete behavior for each relationship to prevent cascading deletes.
/// </summary>
/// <param name="modelBuilder">
/// The <see cref="ModelBuilder"/> used to configure entity mappings and relationships.
/// </param>
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// Index configurations:
// Defining unique indices to enforce uniqueness constraints on certain properties.
// CountryName data of the Conutries table can not have multiple same values.
modelBuilder.Entity<Country>().HasIndex(countryEntity => countryEntity.CountryName).IsUnique();
// CityName data of the Cities table can not have multiple same values.
modelBuilder.Entity<City>().HasIndex(cityEntity => cityEntity.CityName).IsUnique();
// Title data of the Groups table can not have multiple same values.
modelBuilder.Entity<Group>().HasIndex(groupEntity => groupEntity.Title).IsUnique();
// Name data of the Roles table can not have multiple same values.
modelBuilder.Entity<Role>().HasIndex(roleEntity => roleEntity.Name).IsUnique();
// UserName data of the Users table can not have multiple same values.
modelBuilder.Entity<User>().HasIndex(userEntity => userEntity.UserName).IsUnique();
// Defining indices for optimizing query performance on frequently searched properties.
modelBuilder.Entity<User>().HasIndex(userEntity => userEntity.CountryId);
modelBuilder.Entity<User>().HasIndex(userEntity => userEntity.CityId);
// Composite index on FirstName and LastName for optimizing searches involving both fields.
modelBuilder.Entity<User>().HasIndex(userEntity => new { userEntity.FirstName, userEntity.LastName });
// Relationship configurations:
// Configuration should start with the entities that have the foreign keys.
modelBuilder.Entity<City>()
.HasOne(cityEntity => cityEntity.Country) // each City entity has one related Country entity
.WithMany(countryEntity => countryEntity.Cities) // each Country entity has many related City entities
.HasForeignKey(cityEntity => cityEntity.CountryId) // the foreign key property in the City entity that
// references the primary key of the related Country entity
.OnDelete(DeleteBehavior.NoAction); // prevents deletion of a Country entity if there are related City entities
modelBuilder.Entity<UserRole>()
.HasOne(userRoleEntity => userRoleEntity.User) // each UserRole entity has one related User entity
.WithMany(userEntity => userEntity.UserRoles) // each User entity has many related UserRole entities
.HasForeignKey(userRoleEntity => userRoleEntity.UserId) // the foreign key property in the UserRole entity that
// references the primary key of the related User entity
.OnDelete(DeleteBehavior.NoAction); // prevents deletion of a User entity if there are related UserRole entities
modelBuilder.Entity<UserRole>()
.HasOne(userRoleEntity => userRoleEntity.Role) // each UserRole entity has one related Role entity
.WithMany(roleEntity => roleEntity.UserRoles) // each Role entity has many related UserRole entities
.HasForeignKey(userRoleEntity => userRoleEntity.RoleId) // the foreign key property in the UserRole entity that
// references the primary key of the related Role entity
.OnDelete(DeleteBehavior.NoAction); // prevents deletion of a Role entity if there are related UserRole entities
modelBuilder.Entity<User>()
.HasOne(userEntity => userEntity.Country) // each User entity has one related Country entity
.WithMany(countryEntity => countryEntity.Users) // each Country entity has many related User entities
.HasForeignKey(userEntity => userEntity.CountryId) // the foreign key property in the User entity that
// references the primary key of the related Country entity
.OnDelete(DeleteBehavior.NoAction); // prevents deletion of a Country entity if there are related User entities
modelBuilder.Entity<User>()
.HasOne(userEntity => userEntity.City) // each User entity has one related City entity
.WithMany(cityEntity => cityEntity.Users) // each City entity has many related User entities
.HasForeignKey(userEntity => userEntity.CityId) // the foreign key property in the User entity that
// references the primary key of the related City entity
.OnDelete(DeleteBehavior.NoAction); // prevents deletion of a City entity if there are related User entities
modelBuilder.Entity<User>()
.HasOne(userEntity => userEntity.Group) // each User entity has one related Group entity
.WithMany(groupEntity => groupEntity.Users) // each Group entity has many related User entities
.HasForeignKey(userEntity => userEntity.GroupId) // the foreign key property in the User entity that
// references the primary key of the related Group entity
.OnDelete(DeleteBehavior.NoAction); // prevents deletion of a Group entity if there are related User entities
modelBuilder.Entity<ProductStore>()
.HasOne(productStoreEntity => productStoreEntity.Product) // each ProductStore entity has one related Product entity
.WithMany(productEntity => productEntity.ProductStores) // each Product entity has many related ProductStore entities
.HasForeignKey(productStoreEntity => productStoreEntity.ProductId) // the foreign key property in the ProductStore entity that
// references the primary key of the related Product entity
.OnDelete(DeleteBehavior.NoAction); // prevents deletion of a Product entity if there are related ProductStore entities
modelBuilder.Entity<ProductStore>()
.HasOne(productStoreEntity => productStoreEntity.Store) // each ProductStore entity has one related Store entity
.WithMany(storeEntity => storeEntity.ProductStores) // each Store entity has many related ProductStore entities
.HasForeignKey(productStoreEntity => productStoreEntity.StoreId) // the foreign key property in the ProductStore entity that
// references the primary key of the related Store entity
.OnDelete(DeleteBehavior.NoAction); // prevents deletion of a Store entity if there are related ProductStore entities
modelBuilder.Entity<Product>()
.HasOne(productEntity => productEntity.Category) // each Product entity has one related Category entity
.WithMany(categoryEntity => categoryEntity.Products) // each Category entity has many related Product entities
.HasForeignKey(productEntity => productEntity.CategoryId) // the foreign key property in the Product entity that
// references the primary key of the related Category entity
.OnDelete(DeleteBehavior.NoAction); // prevents deletion of a Category entity if there are related Product entities
}
}
}