How migrations work
Entity Framework Core migrations provide a way to incrementally update the database schema to keep it in sync with your data model while preserving existing data.Auto-migration on startup
The API automatically applies pending migrations when it starts. This is configured inProgram.cs:
Creating a new migration
When you add or modify a model in theModels/ directory, you need to create a migration to update the database schema.
1. Navigate to the API project
2. Create the migration
MigrationName with a descriptive name that explains what the migration does. Use PascalCase naming.
Examples:
AddUserActivityTableAddIsActiveToEmployeeUpdateTaxSettingsRemoveUnusedSystemSettingsColumns
3. Review the migration
Entity Framework will generate a new file inMigrations/ with an Up() method (applies changes) and a Down() method (reverts changes).
Review the generated code to ensure it correctly represents your intended changes.
4. Apply the migration
The migration will be automatically applied when you start the API. You can also apply it manually:Common migration commands
List all migrations
View all migrations and their status:Apply migrations
Apply all pending migrations:Revert to a specific migration
Rollback to a previous migration:Remove the last migration
If you haven’t applied the migration yet and want to delete it:Generate SQL script
Generate a SQL script for all migrations without applying them:Development workflow
Adding a new feature
Follow these steps when adding a new feature that requires database changes:- Create model in
BMS_POS_API/Models/ - Add DbSet to
BmsPosDbContext.cs - Create migration:
- Create controller in
BMS_POS_API/Controllers/ - Add React component in
src/frontend/components/ - Add route to
App.tsx
Modifying an existing model
- Update the model class in
Models/ - Create migration:
- Test the migration locally before committing
- Update any affected controllers or services
Migration naming conventions
Use clear, descriptive names that explain what the migration does:Good names
AddUserActivityTable- Adding a new tableAddEmailToEmployee- Adding a columnRemoveObsoleteFields- Removing columnsUpdateProductPriceType- Changing column typesAddIndexToProductBarcode- Adding indexesRenameCustomerToClient- Renaming entities
Avoid
Update1,Fix2,Changes- Not descriptiveNewMigration,Test- Too generictemp,wip- Should never be committed
Migration history
The system maintains a complete migration history in theMigrations/ directory. Current migrations include:
InitialCreate- Initial database schemaAddEmployeeRole- Role-based access controlAddSalesAndSaleItems- Sales transaction tablesAddTaxSettings- Tax configurationAddSystemSettings- System-wide settingsAddReturnsSystem- Returns and refunds functionalityAddUserActivityTable- Audit loggingInventoryFeatures- Advanced inventory managementAddIsActiveToEmployee- Employee activation statusIncreasePinFieldLength- Support for BCrypt hashesAddAdminSettings- Administrative settings
Troubleshooting
Migration fails with constraint errors
Migration fails with constraint errors
If a migration fails due to foreign key constraints:
- Check that all required relationships are defined in the models
- Ensure foreign key columns are nullable if the relationship is optional
- Review the migration’s
Up()method for the correct order of operations - Consider adding data migration logic to populate required foreign keys
Cannot remove migration that's been applied
Cannot remove migration that's been applied
If you need to revert a migration that’s already been applied:
-
Rollback to previous migration:
-
Remove the migration file:
- Make your changes and create a new migration
Entity Framework tools not found
Entity Framework tools not found
If you see “No executable found matching command ‘dotnet-ef’”:Install EF Core tools globally:Update to latest version:Verify installation:
Connection string issues
Connection string issues
If migrations can’t connect to the database:
-
Verify environment variables:
-
Check connection string format:
-
Test connection manually:
-
Ensure
.envfile is in the correct location (project root, not BMS_POS_API/)
Migration generates unexpected changes
Migration generates unexpected changes
If a migration includes changes you didn’t make:
-
Check for uncommitted model changes:
-
Review the migration diff:
-
Verify your DbContext configuration in
BmsPosDbContext.cs -
Remove and recreate the migration if necessary:
Database is out of sync with migrations
Database is out of sync with migrations
If your local database doesn’t match the migration history:
-
Check which migrations are applied:
-
Apply all pending migrations:
-
If database is corrupted, reset it:
-
For production, always backup first:
Best practices
Do
- Create migrations with descriptive names
- Test migrations locally before committing
- Review generated migration code
- Keep migrations small and focused
- Commit migrations with the related code changes
- Back up production databases before applying migrations
Don’t
- Modify migrations after they’re applied to production
- Delete migration files from version control
- Skip reviewing auto-generated migration code
- Create migrations without testing them
- Commit migrations separately from model changes
- Apply untested migrations to production
Production considerations
Automatic migration on startup
The system automatically applies pending migrations when the API starts. This is convenient for development but requires careful consideration for production: Advantages:- No manual migration steps required
- Ensures database is always up-to-date
- Works well with containerized deployments
- Large migrations may delay application startup
- Failed migrations will prevent application from starting
- Multiple instances may try to migrate simultaneously
Alternative: Manual migrations
For production environments, you may prefer to apply migrations manually:- Comment out auto-migration in
Program.cs - Apply migrations before deployment:
- Deploy the application after migrations succeed
Zero-downtime migrations
For critical production systems, follow these steps for zero-downtime migrations:- Make changes backward-compatible (e.g., add nullable columns)
- Deploy application that works with both old and new schema
- Apply migration to add new columns/tables
- Deploy application that uses new schema
- Apply cleanup migration to remove old columns (if needed)