The first section is simple and straight-forward, just enough to get going. Refer to the TLDR section for more information.
dotnet tool update --global dotnet-efSQL Server:
dotnet add package Microsoft.EntityFrameworkCore.SqlServerdotnet add package Microsoft.EntityFrameworkCore.Designdotnet add package Microsoft.EntityFrameworkCore.ToolsSQLite:
dotnet add package Microsoft.EntityFrameworkCore.Sqlitedotnet add package Microsoft.EntityFrameworkCore.Designdotnet add package Microsoft.EntityFrameworkCore.ToolsSQL Server:
dotnet ef dbcontext scaffold "Server=.;Database=MyDb;Trusted_Connection=True;TrustServerCertificate=True" Microsoft.EntityFrameworkCore.SqlServer -o ModelsSQLite:
dotnet ef dbcontext scaffold "Data Source=.\MyDb.sqlite" Microsoft.EntityFrameworkCore.Sqlite -o Models--output or -o => name the output directory in your project for the models
--context or -c => name for db context class or by default database name + "Context"
--schema => SQL only - scaffold only a specific schema (you can use this flag multiple times)
--table => scaffold only a specific table (you can use this flag multiple times)
--force => run after db changes but will overwrite everything!
--no-pluralize => prevents EF from pluralizing/singularizing table/entity names
Microsoft.EntityFrameworkCore.SqlServer
The SQL Server provider. Pulls in the core EF packages (Microsoft.EntityFrameworkCore + Microsoft.EntityFrameworkCore.Relational) transitively. Required when targeting SQL Server.
Microsoft.EntityFrameworkCore.Sqlite
The SQLite provider. Also brings in the core EF packages transitively. Use when targeting SQLite (choose ONE provider per DbContext).
Microsoft.EntityFrameworkCore.Design
Design-time helpers used for scaffolding (database-first reverse engineering), generating migrations, and improving the experience of tools. Needed for dotnet ef dbcontext scaffold and migration generation.
Microsoft.EntityFrameworkCore.Tools
Adds EF Core CLI command integration in the project (so dotnet ef can discover the context and perform operations like scaffold, migrations add/update). Complements the global tool update you run at the top.
Notes:
- You do NOT need to add
Microsoft.EntityFrameworkCoreseparately; the provider already includes it. - For database-first (reverse engineering), you need: provider + Design + Tools.
- For runtime-only (no migrations/scaffolding), you can omit Design/Tools.
-
Specific table(s):
SQL Server
dotnet ef dbcontext scaffold "Server=.;Database=MyDb;Trusted_Connection=True;TrustServerCertificate=True" Microsoft.EntityFrameworkCore.SqlServer -o Models -c MyDbContext --table dbo.Users --table dbo.Orders
SQLite
dotnet ef dbcontext scaffold "Data Source=.\MyDb.sqlite" Microsoft.EntityFrameworkCore.Sqlite -o Models -c MyDbContext --table Users --table Orders
-
Specific schema(s) (SQL Server only):
dotnet ef dbcontext scaffold "Server=.;Database=MyDb;Trusted_Connection=True;TrustServerCertificate=True" Microsoft.EntityFrameworkCore.SqlServer -o Models -c MyDbContext --schema sales --schema hr
-
Output folders (entities) and context folder:
dotnet ef dbcontext scaffold "Server=.;Database=MyDb;Trusted_Connection=True;TrustServerCertificate=True" Microsoft.EntityFrameworkCore.SqlServer \ --output-dir Features\Data\Entities \ --context-dir Features\Data \ --context AppDbContext
-
Overwrite previously generated code:
dotnet ef dbcontext scaffold "Data Source=.\MyDb.sqlite" Microsoft.EntityFrameworkCore.Sqlite -o Models -c MyDbContext --force
-
Prefer attributes over fluent API (Data Annotations):
By default, EF Core generates Fluent API configuration in
OnModelCreating(e.g.,entity.Property(e => e.Name).HasMaxLength(100)). The--data-annotationsflag moves some of that configuration onto your entity classes using attributes like[MaxLength],[Required],[Key], etc.dotnet ef dbcontext scaffold "Server=.;Database=MyDb;Trusted_Connection=True;TrustServerCertificate=True" Microsoft.EntityFrameworkCore.SqlServer -o Models -c MyDbContext --data-annotations
When to use:
- Your entities are used in other layers (e.g., ASP.NET Core model validation) and you want consolidated validation attributes.
- You prefer seeing constraints directly on the properties.
- Simpler for small projects or straightforward schemas.
Trade-offs:
- Not all EF Core configurations have Data Annotation equivalents (e.g., indexes with includes, filter expressions, owned types, table splitting). Complex configurations still require Fluent API.
- Mixing both can get confusing; Fluent API always wins if both are present.
- Attributes couple your domain models to EF/validation concerns.
Default (no flag): All configuration stays in
OnModelCreating, keeping entity classes cleaner and more POCO-like.Plain Old CLR Object - a simple C# class with just properties and no framework-specific attributes or base classes. Keeps your domain models clean and framework-agnostic.
-
Use database names as-is (preserve casing and names exactly as in DB):
By default, EF Core scaffold applies C# naming conventions: table
user_profilebecomes classUserProfile, columnfirst_namebecomes propertyFirstName. The--use-database-namesflag disables this and keeps the exact database names in your C# code.dotnet ef dbcontext scaffold "Data Source=.\MyDb.sqlite" Microsoft.EntityFrameworkCore.Sqlite -o Models -c MyDbContext --use-database-names
When to use:
- Legacy databases with specific naming conventions you must preserve (e.g., all caps, snake_case, Hungarian notation).
- Interop scenarios where external tools/scripts rely on exact DB names.
- You want 1:1 mapping between DB and code for easier cross-referencing.
Trade-offs:
- Your C# code may violate .NET naming conventions (e.g.,
public string user_name { get; set; }instead ofpublic string UserName { get; set; }). - Less idiomatic C# code, harder to read and maintain if database uses non-standard casing.
- Can trigger style warnings/errors if you enforce naming rules via analyzers.
Default (no flag): EF Core pluralizes/singularizes and converts to PascalCase/camelCase following C# conventions, making your entities feel more .NET-native.
-
Don't generate OnConfiguring (when you configure via AddDbContext in Program.cs):
By default, EF Core scaffolding generates an
OnConfiguringmethod in your DbContext with the connection string hardcoded from the scaffold command. The--no-onconfiguringflag omits this method entirely, forcing you to configure the context externally (e.g., via dependency injection inProgram.cs).dotnet ef dbcontext scaffold "Server=.;Database=MyDb;Trusted_Connection=True;TrustServerCertificate=True" Microsoft.EntityFrameworkCore.SqlServer -o Models -c MyDbContext --no-onconfiguring
When to use:
- ASP.NET Core apps where you register the DbContext with
builder.Services.AddDbContext<MyDbContext>(...)inProgram.cs. - You manage connection strings via appsettings.json, user-secrets, or environment variables.
- Multi-environment deployments (dev/staging/prod) where connection strings vary.
- You want to avoid hardcoded connection strings in source code (security best practice).
Trade-offs:
- The generated DbContext won't work standalone without external configuration (e.g., you can't just
new MyDbContext()and use it). - Design-time tools (like future scaffolds or migrations) may require a design-time factory (
IDesignTimeDbContextFactory<MyDbContext>) to work properly. - Slightly more setup required upfront to wire the DbContext into DI.
Default (no flag): Generates
OnConfiguringwith the connection string baked in. Convenient for quick tests/prototypes but not recommended for production apps.Example external configuration (Program.cs):
builder.Services.AddDbContext<MyDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
// Needed for design-time operations when using --no-onconfiguring public class MyDbContextFactory : IDesignTimeDbContextFactory<MyDbContext> { public MyDbContext CreateDbContext(string[] args) { var optionsBuilder = new DbContextOptionsBuilder<MyDbContext>(); optionsBuilder.UseSqlServer("Server=.;Database=MyDb;Trusted_Connection=True;TrustServerCertificate=True"); return new MyDbContext(optionsBuilder.Options); } }
- ASP.NET Core apps where you register the DbContext with
Tips:
- Keep your connection string in user-secrets or environment variables for real apps; pass it via PowerShell interpolation if needed.
- Add
TrustServerCertificate=Trueonly for dev or when appropriate. - Re-run with
--forceafter DB changes to refresh the generated code.