CodeFirstDbGenerator 6.0.0

dotnet add package CodeFirstDbGenerator --version 6.0.0                
NuGet\Install-Package CodeFirstDbGenerator -Version 6.0.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CodeFirstDbGenerator" Version="6.0.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add CodeFirstDbGenerator --version 6.0.0                
#r "nuget: CodeFirstDbGenerator, 6.0.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install CodeFirstDbGenerator as a Cake Addin
#addin nuget:?package=CodeFirstDbGenerator&version=6.0.0

// Install CodeFirstDbGenerator as a Cake Tool
#tool nuget:?package=CodeFirstDbGenerator&version=6.0.0                

CodeFirstDbGenerator 6

A Lightweight Library to generate quickly Databases from entities.

Concepts:

  • 0 Migration. No "MigrationsHistory" table. Avoids a directory with hundred of migrations.
  • Scaffold command to generate/synchronize entities, DbModel and Snapshot with Database
  • Generate script or update database command to update the database

Db Supported: SQL Server, SQLite, MySQL|MariaDB, PostgreSQL

Installation

  1. Library: SQL Server, SQLite, MySQL, PostgreSQL (CodeFirstDbGenerator is installed as dependency)

Sample:

install-package CodeFirstDbGenerator.SqlServer
  1. Tool

For the NuGet Package Manager Console in Visual Studio (CodeFirstDbGenerator.Tools)

install-package CodeFirstDbGenerator.Tools

OR the .NET CLI tool (dotnet-cf)

dotnet tool install --global dotnet-cf

Tip: uninstall a previous version or list the tools

dotnet tool uninstall -g dotnet-cf 
dotnet tool list -g

Or package references

<PackageReference Include="CodeFirstDbGenerator.SqlServer" Version="6.0.0" />
<PackageReference Include="CodeFirstDbGenerator.Tools" Version="6.0.0">
    <PrivateAssets>all</PrivateAssets>
    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

Note: it's possible to invoke the commands from code (or create a GUI tool). Use:

  • ScaffoldDbModelService
  • GenerateScriptService
  • UpdateDatabaseService

Scaffold DbModel Command

To generate/synchronize entities, DbModel and Snapshot with Database

Option Description
-Project The name of the project
-StartupProject The name of the Startup project
-Connection The connection string
-Provider The provider to use (for example CodeFirstDbGenerator.SqlServer)
-OutputDir The directory to put the files in
-DataAnnotations To use Data Annotations
-Views To include Views
-Tables To filter the tables to use (for example -Tables Table1,Table2)

Sample:

Scaffold-DbModel "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=Northwind;Integrated Security=True;" CodeFirstDbGenerator.SqlServer -OutputDir Model

It's possible to create a custom provider that implements IDesignTimeService to configure TypeMapping or services.

Sample with dotnet-cf

dotnet-cf scaffold dbmodel -a "C:\Samples\Sample\bin\Release\net5.0-windows\Sample.dll" -c "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=Northwind;Integrated Security=True;" -p "CodeFirstDbGenerator.SqlServer" -o "Model" -t Categories -t Employees

Generate Script Command

Allows to generate a SQL script

Option Description
-Project The name of the project
-StartupProject The name of the Startup project
-DbModel The DbModel to use
-Output The output file path
-Create Create tables script

Samples:

Only for changes

Generate-Script

Initial Create Database Script

Generate-Script -DbModel NorthwindModel -Create

Sample with dotnet-cf

dotnet-cf generate script -a "C:\Samples\Sample\bin\Release\net5.0-windows\Sample.dll" -d NorthwindModel --create

Update Database Command

Allows to update the database

Option Description
-Project The name of the project
-StartupProject The name of the Startup project
-DbModel The DbModel to use
-Drop To drop and recreate the database
-Verbose To report operations executed

Sample:

Update-Database -Drop -Verbose

Sample with dotnet-cf

dotnet-cf database update -a "C:\Samples\Sample\bin\Release\net5.0-windows\Sample.dll" -d NorthwindModel --drop --verbose

Create a DbModel

  • With ServiceCollection extensions
  • Or override OnConfiguring DbModel method

With OnConfiguring

public class BlogModel : DbModel
{
    public override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Category>();
        modelBuilder.Entity<Author>();
        modelBuilder.Entity<Post>();
    }

    public override void OnConfiguring(DbModelOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=Sample;Trusted_Connection=True;MultipleActiveResultSets=true");
    }
}

OR With ServiceCollection Extensions

public class BlogModel : DbModel
{
    // 1. Add a constructor with Generic DbModelOptions
    public BlogModel(DbModelOptions<BlogModel> options)
        : base(options)
    { }

    public override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Category>();
        modelBuilder.Entity<Author>();
        modelBuilder.Entity<Post>();
    }
}
// 2. Registering the DbModel and the connection string to use
services.AddDbModel<BlogModel>(options =>options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

Example for Sqlite

services.AddDbModel<SqliteDbModel>(options => options.UseSqlite(@"Data Source=C:\Db\Sample.db")); // dont use relative path

Data Annotations and / OR Fluent API

Two way to define columns and constraints:

  • By Data Annotations attributes
  • By Fluent Api

Conventions

Conventions are used to discover Data Annotations attributes and constraints. It's possible to change the conventions:

public class SampleModel : DbModel
{
    // etc.

    public override void ConfigureConventions(ConventionSet conventions)
    {
        // sample remove a convention
        conventions.ModelFinalizingConventions.Remove<NavigationDiscoveryConvention>();
    }
}

Data Annotations Attributes

  • Key: for primary key (identity if int, short or long). For composite primary key use fluent api.
  • Required attribute
  • Table: to define table name
  • Column: to define column name and type name
  • DatabaseGenerated + identity option: for a column identity
  • StringLength or MaxLength: to define string length (exeample "navarchar(100)")
  • Timestamp attribute
  • ForeignKey: to specify the property name

🚀 nullable enable detected

// [Table("MyCompanies", Schema = "MySchema")] 
public class Company
{
    // [Key] // or not identity [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int CompanyId { get; set; } // key

    [StringLength(100)]
    public string Name { get; set; } = null!;

    //[Column("MyPostalCode")] allows to rename the column
    public string PostalCode { get; set; } = null!; 

    [Column(TypeName = "text")] // allows to change the type
    public string? Address { get; set; }

    [MaxLength(50)] // or [StringLength(50)]
    public string? City { get; set; } // not required

    [Timestamp]
    public byte[] RowVersion { get; set; } = null!;

    public List<Employee> Employees { get; set; } = new();
}

public class Employee
{
    public int EmployeeId { get; set; } 
    public string FirstName { get; set; } = null!;
    public string LastName { get; set; } = null!;

    public int CompanyId { get; set; } // foreign key auto detected
    public Company Company { get; set; } = null!;

    [NotMapped] // ignored
    public string FullName
    {
        get { return $"{FirstName} {LastName}"; }
    }
}

Or configure properties with Fluent Api. Samples:

modelBuilder.Entity<Category>()
    .Property(x => x.Name)
    .HasColumnName("CategoryName")
    .NotNull()
    .HasDefaultValue("My default value");

modelBuilder.Entity<Category>()
    .Property(x => x.Id)
    .Identity(5,5);

modelBuilder.Entity<Post>()
    .Property(x => x.CreatedAt)
    .HasDefaultValueSql("CURRENT_TIMESTAMP");

Primary Key

Auto detected if property name equals "Class name + Id" Or "Id"

public class Author
{
    public int AuthorId { get; set; }
    // or
    // public int Id { get; set; }
}

Use Fluent API for a composite Key

modelBuilder.Entity<Book>().HasKey(x => new { x.Id1, x.Id2 });

HasOne (foreign key)

Auto detected if property equals "Principal" class name + Id

public class Author
{
    public int AuthorId { get; set; }
}

public class Post
{
    public int PostId { get; set; }

    public int AuthorId { get; set; } 
    public Author Author { get; set; } // navigation required
}

With Foreign key Attribute on Navigation

public class Post
{       
    public int PostId { get; set; }

    public int TheAuthorId { get; set; }
    [ForeignKey(nameof(TheAuthorId))]
    public Author TheAuthor { get; set; }
}

... or on properties

public class Author
{
    public int AuthorId { get; set; }
}

public class Post
{
    public int PostId { get; set; }

    [ForeignKey(nameof(TheAuthor))]
    public int TheAuthorId { get; set; }
    public Author TheAuthor { get; set; }
}

With Fluent Api

modelBuilder.Entity<Post>().HasOne(x => x.Author).WithForeignKey(x => x.AuthorId).WithName("FK_Posts_Authors");

HasMany

When a Many to Many relation is detected, a relation table ("PostCategory" for example) is created

public class Post
{
    public int PostId { get; set; }
    // etc.

    public List<Category> Categories { get; set; } // <=
}

public class Category
{
    public int CategoryId { get; set; }
    // etc.

    public List<Post> Posts { get; set; } // <=
}

With Fluent Api

modelBuilder.Entity<Post>().HasMany(x => x.Categories);
modelBuilder.Entity<Category>().HasMany(x => x.Posts);

Samples

Create and use a Sequence with SQL Server

public class SampleModel : DbModel
{
    public override void OnModelCreating(ModelBuilder modelBuilder)
    {
            modelBuilder.HasSql(@"
IF OBJECT_ID('dbo.MySequence') IS NULL 
BEGIN
CREATE SEQUENCE [MySequence] AS [int] 
START WITH 1000 
INCREMENT BY 5;
END", SqlPosition.BeforeAllQueries);

        modelBuilder.Entity<Category>()
            .Property(x => x.Id)
            .HasDefaultValueSql("(NEXT VALUE FOR [MySequence])");

        modelBuilder.Entity<Category>().HasKey(x => x.Id);
    }

    public override void OnConfiguring(DbModelOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer("Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=SampleDb;Integrated Security=True;");
    }
}

public class Category
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Configure a WPF App to use Microsoft.Extensions.DependencyInjection

Install packages

<ItemGroup>
	<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0" />
</ItemGroup>

Add a CreateHostBuilder function to the entry point of the application

using CodeFirstDbGenerator;
using CodeFirstDbGenerator.SqlServer;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Sample.Data;
using System;
using System.Windows;

namespace WpfDi
{
    public partial class App : Application
    {
        private IHost host;

        public App()
        {
            host = CreateHostBuilder().Build();
        }

        private void Application_Startup(object sender, StartupEventArgs e)
        {
            host.Start();

            var shell = host.Services.GetRequiredService<MainWindow>();
            shell.Show();
        }

        public static IHostBuilder CreateHostBuilder() =>
            Host.CreateDefaultBuilder()
            .ConfigureServices((context, services) =>
            {
                services.AddScoped<MainWindow>();
                services.AddDbModel<MyDbModel>(options => options.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=TestWpfDi;Trusted_Connection=True;"));
            });
    }
}

Create a custom Provider for Scaffolding

public class CustomDesignTimeService : IDesignTimeService
{
    // services used by Scaffold command
    public void ConfigureDesignTimeServices(IServiceCollection services)
    {
        services
            .AddTransient<IDatabaseModelFactory, SqlServerDatabaseModelFactory>()
            .AddTransient<ITypeMappingSource, CustomSqlServerTypeMappingSource>() // use custom type mapping source
            .AddTransient<IEntityNamer, EntityNamer>()
            .AddTransient<IPropertyNamer, PropertyNamer>()
            .AddTransient<IModelMapper, ModelMapper>()
            .AddTransient<IMigrationOperationsMapper, MigrationOperationsMapper>()
            .AddTransient<IEntityCodeGenerator, CSharpEntityCodeGenerator>()
            .AddTransient<IDbModelCodeGenerator, CSharpDbModelCodeGenerator>()
            .AddTransient<IDatabaseModelSnapshotCodeGenerator, CSharpDatabaseModelSnapshotCodeGenerator>();
    }
}

public class CustomSqlServerTypeMappingSource : SqlServerTypeMappingSource
{
    public CustomSqlServerTypeMappingSource()
    {
        // custom Mapping with JArray (Json.Net) for example
        AddOrReplaceTypeMapping(typeof(JArray), ClrTypeMapping.Default(typeof(JArray), "text"));
        AddOrReplaceColumnMapping(new ColumnMapping("dbo", "MyTable", "MyColumn", typeof(JArray), "text"));
    }
}

Replace the Provider by the name of the project with the custom DesignTimeService

Scaffold-DbModel "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=SampleDb;Integrated Security=True;" MyProject -OutputDir Model

Seed database

Use HasSql method. Sample with SQL Server:

modelBuilder.HasSql(@"
IF((SELECT COUNT(*) FROM [Categories])=0)
BEGIN
INSERT INTO [Categories]([Name]) VALUES('Category A'),('Category B'),('Category C');
END", SqlPosition.AfterAllQueries);

OR use a Library like SDE or Dapper and override OnMigrated or OnMigrationCompleted methods of the DbModel.

Product Compatible and additional computed target framework versions.
.NET net5.0 is compatible.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (4)

Showing the top 4 NuGet packages that depend on CodeFirstDbGenerator:

Package Downloads
CodeFirstDbGenerator.SqlServer

A Lightweight Library to generate quickly Databases from entities. Concepts: - 0 Migration. No "MigrationsHistory" table. Avoids a directory with hundred of migrations. - Scaffold command to generate/synchronize entities, DbModel and Snapshot with Database - Generate script or update database command to update the database Db Supported: SQL Server, SQLite, MySQL|MariaDB, PostgreSQL

CodeFirstDbGenerator.Sqlite

A Lightweight Library to generate quickly Databases from entities. Concepts: - 0 Migration. No "MigrationsHistory" table. Avoids a directory with hundred of migrations. - Scaffold command to generate/synchronize entities, DbModel and Snapshot with Database - Generate script or update database command to update the database Db Supported: SQL Server, SQLite, MySQL|MariaDB, PostgreSQL

CodeFirstDbGenerator.MySql

A Lightweight Library to generate quickly Databases from entities. Concepts: - 0 Migration. No "MigrationsHistory" table. Avoids a directory with hundred of migrations. - Scaffold command to generate/synchronize entities, DbModel and Snapshot with Database - Generate script or update database command to update the database Db Supported: SQL Server, SQLite, MySQL|MariaDB, PostgreSQL

CodeFirstDbGenerator.Npgsql

A Lightweight Library to generate quickly Databases from entities. Concepts: - 0 Migration. No "MigrationsHistory" table. Avoids a directory with hundred of migrations. - Scaffold command to generate/synchronize entities, DbModel and Snapshot with Database - Generate script or update database command to update the database Db Supported: SQL Server, SQLite, MySQL|MariaDB, PostgreSQL

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
6.0.0 1,178 7/30/2022
5.8.1 1,150 4/6/2022
5.8.0 1,130 4/5/2022
5.7.2 1,063 4/3/2022
5.7.0 1,141 4/2/2022
5.2.5 945 3/17/2022
4.0.3 976 1/13/2022
4.0.2 464 1/11/2022
4.0.1.1 288 12/28/2021
4.0.0.1 345 12/28/2021
3.2.0 532 12/19/2021
3.1.0.3 303 12/18/2021
3.1.0 291 12/18/2021
3.0.1.6 562 12/17/2021
2.0.8 419 12/7/2021
1.2.0.2 2,083 11/26/2021
1.2.0.1 389 11/22/2021
1.1.1 1,198 11/20/2021
1.1.0 824 11/19/2021
1.0.1.1 438 11/18/2021

DefaultValue, DefaultValueSql