Skip to content

meineGlock20/efcore-database-first-cheatsheet

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 

Repository files navigation

EF CORE Cheat Sheet for Database First

Updated 2025-11-08

The first section is simple and straight-forward, just enough to get going. Refer to the TLDR section for more information.

Always run this first to make sure your global tools are updated.

dotnet tool update --global dotnet-ef

Install Nuget Packages - this will install the latest stable release.

SQL Server:

dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Microsoft.EntityFrameworkCore.Tools

SQLite:

dotnet add package Microsoft.EntityFrameworkCore.Sqlite
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Microsoft.EntityFrameworkCore.Tools

Scaffold the entire database.

SQL Server:

dotnet ef dbcontext scaffold "Server=.;Database=MyDb;Trusted_Connection=True;TrustServerCertificate=True" Microsoft.EntityFrameworkCore.SqlServer -o Models

SQLite:

dotnet ef dbcontext scaffold "Data Source=.\MyDb.sqlite" Microsoft.EntityFrameworkCore.Sqlite -o Models

Common Flags

--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

<TLDR/>

What each Nuget package does

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.EntityFrameworkCore separately; 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.

Common Scaffolding variations (mix and match)

  • 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-annotations flag 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_profile becomes class UserProfile, column first_name becomes property FirstName. The --use-database-names flag 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 of public 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 OnConfiguring method in your DbContext with the connection string hardcoded from the scaffold command. The --no-onconfiguring flag omits this method entirely, forcing you to configure the context externally (e.g., via dependency injection in Program.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>(...) in Program.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 OnConfiguring with 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);
        }
    }

Tips:

  • Keep your connection string in user-secrets or environment variables for real apps; pass it via PowerShell interpolation if needed.
  • Add TrustServerCertificate=True only for dev or when appropriate.
  • Re-run with --force after DB changes to refresh the generated code.

About

EF CORE Cheat Sheet for Database First.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published