# 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
<ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.0" />
</ItemGroup>
```

## 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<OnePlanDbContext> 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<OnePlanDbContext>(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<BudgetConfig> BudgetConfigs { get; set; }
    public DbSet<DimDepartment> 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<BudgetConfig> BudgetConfigs { get; set; }
}

public class FrameworkDbContext : DbContext
{
    // Only fw schema tables
    public DbSet<DimDepartment> 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