# Entity Framework Database-First Setup Guide ## Project Structure Your solution should follow this structure for optimal organization: ``` YourSolution/ ├── src/ │ ├── OnePlan/ <- Your project │ │ ├── Controllers/ │ │ ├── Models/ <- Scaffolded models will go here │ │ └── Data/ <- DbContext will go here ├── tests/ │ └── OnePlan.Tests/ ├── tools/ │ └── scaffold.bat <- Scaffolding script here └── YourSolution.sln ``` ## Prerequisites Before starting, ensure you have: 1. .NET SDK installed 2. Entity Framework Core tools installed globally: ```bash dotnet tool install --global dotnet-ef ``` 3. Required NuGet packages in your project: ```xml ``` ## Scaffolding Process ### Step 1: Create Scaffold Script Create a file named `scaffold.bat` in your `tools` directory with the following content: ```bat @echo off cd ..\src\OnePlan dotnet ef dbcontext scaffold^ "Server=your_server;Database=your_database;User=your_user;Password=your_password;TrustServerCertificate=True;Encrypt=True;"^ Microsoft.EntityFrameworkCore.SqlServer^ --project OnePlan.csproj^ --context-dir Data^ --output-dir Models^ --context OnePlanDbContext^ --force^ --data-annotations^ --no-onconfiguring^ -t fp.AddProviderEncountersDataForCharges^ -t fp.AddProviderSummary^ -t fp.AdjustmentChunkingConfiguration^ -t fp.APEDepartmentWorkflowStatus^ -t fp.APEWorkflow^ -t fp.BenefitsSpreads^ -t fp.BudgetConfig^ -t fp.BudgetConfigDefaultSetting^ -t fp.BudgetConfigSetting^ -t fp.BudgetRefreshRequest^ -t fp.BudgetRefreshRequestHistory^ -t fp.ChargeVolumeAddProviderAdjustment^ -t fp.ChargeVolumeSpreads^ -t fp.DataRefreshTargetThreshold^ -t fp.DepartmentChargeVolumeAdjustment^ -t fp.DepartmentConfig^ -t fp.DimCategory^ -t fw.DimDepartment^ -t dss.DimPhysician^ -t fp.EngineLog^ -t fp.EntityGroupConfig^ -t fp.FixChangeHistoryRequest^ -t fp.GeneralLedger^ -t fp.GeneralLedgerInitialPlanConfigDetail^ -t fp.GeneralLedgerSpreads^ -t fp.InitialPlanRule^ -t dbo.LOCK^ -t dbo.log^ -t dbo.OnePlanPerformanceTestHistory^ -t fp.OnePlanPerformanceTestValidationResult^ -t fp.PerformanceTestingSetting^ -t fp.ProviderCompensationSpreads^ -t fp.SamplingLog^ -t fp.ScheduledRefreshRequest^ -t fp.ServiceLineEncounterSpreads^ -t fp.SettingCategory^ -t fp.SpreadHistory^ -t fp.StaffingInitialPlanConfigDetail^ -t fp.StaffingSpreads^ -t fp.StatisticsSpreads^ -t fp.SystemSetting^ -t dbo.TEScheduledTask^ -t dbo.UserProfile^ -t fp.viewBenefitsAdjustment^ -t fp.viewDepartmentChargeVolumeAdjustment^ -t fp.viewGeneralLedgerAdjustment^ -t fp.viewReimbursementAdjustment^ -t fp.viewReimbursementGeneralLedgerAdjustment^ -t fp.viewServiceLineEncounterAdjustment^ -t fp.viewStaffingAdjustment^ -t fp.viewStatisticsAdjustment pause ``` Important Notes for Multi-line Batch Files: 1. The `^` character must be the last character on each line (no spaces after it) 2. Each new line should start with a space before the parameter 3. The connection string must be in quotes 4. The last command line doesn't need a `^` 5. Use `..\` instead of `../` for Windows paths To run the scaffold script: 1. Open command prompt 2. Navigate to the tools directory: `cd tools` 3. Run: `scaffold.bat` ### Step 2: Configure Connection String Add your connection string to `appsettings.json`: ```json { "ConnectionStrings": { "DefaultConnection": "Server=your_server;Database=your_database;User=your_user;Password=your_password;TrustServerCertificate=True;Encrypt=True;" } } ``` ### Step 3: Set Up Dependency Injection 1. Modify the generated DbContext to use constructor injection: ```csharp public class OnePlanDbContext : DbContext { public OnePlanDbContext(DbContextOptions options) : base(options) { } // Your DbSet properties will be here } ``` 2. Register the DbContext in `Program.cs`: ```csharp var builder = WebApplication.CreateBuilder(args); // Add DbContext builder.Services.AddDbContext(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))); ``` ## DbContext Organization You have two main approaches for organizing your DbContext: 1. **Single DbContext (Recommended for this project)** ```csharp public class OnePlanDbContext : DbContext { // All tables from all schemas public DbSet BudgetConfigs { get; set; } public DbSet DimDepartments { get; set; } // ... etc for all tables } ``` Advantages: - Simpler to manage - All relationships maintained automatically - Better for cross-schema transactions - Easier to maintain data consistency - Single dependency to inject 2. **Multiple DbContexts by Schema** ```csharp public class FinancialPlanningDbContext : DbContext { // Only fp schema tables public DbSet BudgetConfigs { get; set; } } public class FrameworkDbContext : DbContext { // Only fw schema tables public DbSet DimDepartments { get; set; } } ``` Advantages: - Better separation of concerns - More focused contexts - Can be more performant for specific schema operations - Better for microservices architecture For this project, the single DbContext approach is recommended due to: - Highly interconnected tables - Cross-schema queries - Views joining data across schemas - Coherent domain model around financial planning ## Notes - Views are included in the scaffold and will be read-only - The scaffold includes all specified tables across multiple schemas - Relationships between tables will be automatically mapped - Generated models will be placed in the Models directory - DbContext will be placed in the Data directory - Use data annotations for simple configurations - Use fluent API in OnModelCreating for complex configurations