A Roslyn Source Generator that generates C# EF Core binding classes and TypeScript enums from SQL schema files.
- No database connection required - Reads SQL files directly from your database project
- C# generation: Entity binding classes, PrimaryKey wrappers, navigation properties
- TypeScript generation: Enum definitions, lookup arrays, dropdown options
- Incremental generation - Only regenerates when SQL files change
- Git history preservation - Writes to disk with same filenames for clean diffs
<PackageReference Include="SqlCodeGen" Version="1.0.0"
OutputItemType="Analyzer"
ReferenceOutputAssembly="false" />Add to your EF Models project .csproj:
<PropertyGroup>
<!-- Required: Namespace for generated C# code -->
<SqlCodeGen_Namespace>MyProject.EFModels.Entities</SqlCodeGen_Namespace>
<!-- Optional: Output directory for TypeScript enums -->
<SqlCodeGen_TypeScriptOutputDir>..\MyProject.Web\src\app\shared\generated\enum</SqlCodeGen_TypeScriptOutputDir>
<!-- Optional: Output directory for C# files (for git history preservation) -->
<SqlCodeGen_OutputDir>Entities\Generated\ExtensionMethods</SqlCodeGen_OutputDir>
<!-- Optional: Tables to exclude from generation -->
<SqlCodeGen_ExcludeTables>DatabaseMigration,__RefactorLog</SqlCodeGen_ExcludeTables>
</PropertyGroup>
<!-- Import props (for project reference) or auto-imported via NuGet -->
<Import Project="..\SqlCodeGen\build\SqlCodeGen.props" />
<!-- SQL files for the Source Generator to process -->
<ItemGroup>
<AdditionalFiles Include="..\MyProject.Database\dbo\Tables\*.sql" />
<AdditionalFiles Include="..\MyProject.Database\Scripts\LookupTables\*.sql" />
<!-- Required for TypeScript generation -->
<SqlCodeGenTableSql Include="..\MyProject.Database\dbo\Tables\" />
<SqlCodeGenLookupTableSql Include="..\MyProject.Database\Scripts\LookupTables\" />
</ItemGroup>
<!-- If writing to disk, exclude from compilation (already compiled by generator) -->
<ItemGroup Condition="'$(SqlCodeGen_OutputDir)' != ''">
<Compile Remove="$(SqlCodeGen_OutputDir)\*.Binding.cs" />
<Compile Remove="$(SqlCodeGen_OutputDir)\*PrimaryKey.cs" />
</ItemGroup>C# Binding Class ({TableName}.Binding.cs):
- Static readonly instances for each enum value
Alllist andAllLookupDictionaryfor lookups- Strongly-typed enum
ToType()andToEnumconversion methods- Navigation properties to other lookup tables
TypeScript Enum ({table-name}-enum.ts):
- Enum definition
LookupTableEntry[]arraySelectDropdownOption[]for dropdowns
C# Binding Class ({TableName}.Binding.cs):
FieldLengthsstatic class with max lengths for string columns- Navigation properties to lookup tables
C# PrimaryKey Wrapper ({TableName}PrimaryKey.cs):
- Strongly-typed primary key wrapper class
CREATE TABLE [dbo].[ProjectStage](
[ProjectStageID] [int] NOT NULL,
[ProjectStageName] [varchar](100) NOT NULL,
[ProjectStageDisplayName] [varchar](100) NOT NULL,
[SortOrder] [int] NOT NULL,
CONSTRAINT [PK_ProjectStage] PRIMARY KEY CLUSTERED ([ProjectStageID])
)MERGE INTO [dbo].[ProjectStage] AS Target
USING (VALUES
(1, 'Proposal', 'Proposal', 10),
(2, 'PlanningDesign', 'Planning/Design', 20),
(3, 'Implementation', 'Implementation', 30)
) AS Source (ProjectStageID, ProjectStageName, ProjectStageDisplayName, SortOrder)
ON Target.ProjectStageID = Source.ProjectStageID
WHEN MATCHED THEN UPDATE SET ...
WHEN NOT MATCHED THEN INSERT ...;This is a development-only dependency. The generated files are committed to git, so production builds just compile the checked-in files:
<!-- Only include generator in Debug builds -->
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
<PackageReference Include="SqlCodeGen" Version="1.0.0" ... />
</ItemGroup>MIT