FreeSql.Generator How is the command line code generator implemented



  • Introduction to FreeSQL
  • FreeSql.Generator
  • RazorEngine.NetCore
  • Source code analysis
  • FreeSql.Tools


FreeSQL is a powerful object relational mapping technology (O / RM), which supports. NETCORE 2.1 + or. Net framework 4.0 + or xamarin.

We also have a powerful ORM generator to develop.

In general, we develop database related applications, mainly divided into three types of code first, DB first, model first

I’ve only used the first two,

  • Code first, code first. Databases are generated according to entity classes. All relationships can be logical or physical.
  • DB first: database first, design table structure directly, generate table with design tools, design primary key, foreign key, index, association relationship, etc.

When we use DB first, how can we generate some entity classes, general code, controller, service layer and dto for the designed database. Today, I’d like to introduce some tools in the FreeSQL project. Of course, small partners who do not use this ORM can also use this tool because it is universal.

FreeSql.Generator Command line mode

Through a few lines of commands, we can generate the common code structure in the project. We don’t need to copy a piece of code and modify it. We can speed up the development, reduce the duplication of labor and use a hair less.

As everyone’s project structure and code location are different, different business logic is different for ORM, so there is no corresponding template for this project. I believe that students who have used razor will be able to implement their own templates.

1-2 years ago, a senior student and I also wrote code generator. Here are some templates for the project, The project is based on. Net core + razor page, Due to the resignation, they did not continue to maintain. These templates were all related to ABP. At that time, some general functions were extracted. Single table operation could directly generate the front and back-end functions. You only need to write the document of the data dictionary in word in a unified format and copy it to the system. Then, the fields can be parsed according to the blank space and definition type.

go back to FreeSql.Generator command line

  • For the use of this tool, please refer to
  • Source location
  • The premise is that the. Net core 3.1 SDK is installed locally

How to use it.

  1. Install dotnet tool to generate entity class
dotnet tool install -g FreeSql.Generator
  1. Create a new directory, enter CMD in the address bar to quickly open the command window, and enter the command:
FreeSql.Generator --help

We can see that

C:\Users\igeekfan\Desktop\code>FreeSql.Generator --help
        ____                   ____         __
       / __/  ____ ___  ___   / __/ ___ _  / /
      / _/   / __// -_)/ -_) _\ \  / _ `/ / /
     /_/    /_/   \__/ \__/ /___/  \_, / /_/

  # Github # v1.5.0

    Using FreeSQL to quickly generate entity class of database

    Update tool: dotnet tool update - G FreeSql.Generator

  #Quick start#

  > FreeSql.Generator -Razor 1 -NameOptions 0,0,0,0 -NameSpace MyProject -DB "MySql,Data Source=;..."

     -Razor 1 * select template: entity class + properties

     -Razor 2 * selection template: entity class + attribute + navigation attribute

     -Razor "d:\ diy.cshtml "* custom template file

     -Nameoptions * has four Boolean values, corresponding to:
                               #Capital letters
                               #Capital letters,其他小写
                               #All lowercase
                               #Underline to hump

     -Namespace * namespace

     -DB "mysql, data source =; port = 3306; user id = root; password = root; initial catalog = database; charset = utf8; sqlmode = none; max pool size = 2"

     -DB "sqlserver, data source =.; integrated security = true; initial catalog = database; pooling = true; max pool size = 2"

     -DB "PostgreSQL, host =; port = 5432; username = Postgres; password = 123456; database = database; pooling = true; maximum pool size = 2"

     -DB "Oracle,user id=user1;password=123456;data source=//;Pooling=true;Max Pool Size=2"

     -DB "Sqlite,Data Source=document.db"

     -DB "Dameng,server=;port=5236;user id=2user;password=123456789;database=2user;poolsize=2"
                               Dameng is a domestic Dameng database

     -Filter                   Table+View+StoreProcedure
                               Default generation: Table + view + stored procedure
                               If you do not want to generate views and stored procedures - filter view + storeprocedure

     -Match regular expression. Only matching tables are generated, such as dbo \. TB_ +.

     -File name, default: {name}. CS

     -Output save path, default to the current shell directory
                               It is recommended to create in the entity class directory gen.bat , double-click it to reset all entity classes
  • Update command line
dotnet tool update -g FreeSql.Generator
  1. Here, Lin CMS dotnetcore is used to test.

  • Database table names are underlined, and fields are also underlined.
  • -Razor specifies the first template
  • -Nameoptions 0,0,0,1, the last 1, represents the underline to hump, meeting the C ා naming rule
  • -The namespace specifies the namespace LinCms.Core.Entities
  • -DB is the database configuration
  • MySQL local address 3306 port user name root password 123456 database Lin CMS
  • -In this way, only books can be generated, and regular expressions, such as – Math Lin, are supported_ User will generate Lin_ Table that starts with user. as dbo.TB_ . + will generate tables starting with TB. That is, only matching tables are generated
  1. Execute this command.
FreeSql.Generator -Razor 1  -NameOptions 0,0,0,1 -NameSpace LinCms.Core.Entities -DB "MySql,Data Source=;Port=3306;User ID=root;Password=123456;Initial Catalog=lincms;Charset=utf8;SslMode=none;Max pool size=2"

At this point, the code has been generated

One of the code generation is as follows. These classes are partial. Those who are familiar with C ා should know that this keyword is used in the definition of class, and we can extend it in different places. To prevent the loss of changed fields when resynchronizing the structure of the database.

namespace LinCms.Core.Entities {

	[JsonObject(MemberSerialization.OptIn), Table(Name = "book")]
	public partial class Book {

		///Primary key ID
		[JsonProperty, Column(Name = "id", IsPrimary = true, IsIdentity = true)]
		public long Id { get; set; }

		[JsonProperty, Column(Name = "author", DbType = "varchar(20)")]
		public string Author { get; set; } = string.Empty;

		[JsonProperty, Column(Name = "image", DbType = "varchar(50)")]
		public string Image { get; set; } = string.Empty;

        //More XXX

  • The final effect is as follows

Two files are generated
Wei Regenerate. Bat. The next time you click it, you can regenerate the entity class.

FreeSql.Generator -Razor "__razor.cshtml.txt" -NameOptions 1,1,0,1 -NameSpace MyProject -DB "MySql,Data Source=;Port=3306;User ID=root;Password=123456;Initial Catalog=lincms;Charset=utf8;SslMode=none;Max pool size=2" -FileName "{name}.cs"

The above command – razor specifies the txt file__ razor.cshtml.txt

We can define our own templates to generate code that is in line with our own business, so as to achieve rapid development.

We can take a look at the content of the file in the template. He is Under the MVC structure of the razor back-end template rendering, remove this. TXT suffix, it is very clear. about MVC razor, we can replace the values in cshtml with the values of methods under the controller. This process is implemented by a class library called razorengine, but that is a practice under the. Net framework. Introduction to code generation of razorengine under. Net framework

@using FreeSql.DatabaseModel;@{
var gen = Model as RazorModel;

Func GetAttributeString = attr => {
	if (string.IsNullOrEmpty(attr)) return null;
	return string.Concat(", ", attr.Trim('[', ']'));
Func GetDefaultValue = col => {
    if (col.CsType == typeof(string)) return " = string.Empty;";
    return "";
namespace @gen.NameSpace {

@if (string.IsNullOrEmpty(gen.table.Comment) == false) {
	@:/// @gen.table.Comment.Replace("\r\n", "\n").Replace("\n", "\r\n		/// ")
	public partial class @gen.GetCsName(gen.FullTableName) {

	@foreach (var col in gen.columns) {

		if (string.IsNullOrEmpty(col.Coment) == false) {
		@:/// @col.Coment.Replace("\r\n", "\n").Replace("\n", "\r\n		/// ")
		@:@("[JsonProperty" + GetAttributeString(gen.GetColumnAttribute(col)) + "]")
		@:public @gen.GetCsType(col) @gen.GetCsName(col.Name) { get; set; }@GetDefaultValue(col)


In the era of. Net core, I have a look FreeSql.Generator Use this class library RazorEngine.NetCore To realize the dynamic operation of cshtml and generate the required text.

Razor engine is a template engine based on Microsoft’s razor parsing. It allows you to build dynamic templates using razor syntax. You only need to use the static method of engine, Engine.Razor.RunCompile Etc.

Create a console app and install the package.

Install-Package RazorEngine.NetCore
using RazorEngine;
using RazorEngine.Templating; // For extension methods.

string template = "Hello @Model.Name, welcome to RazorEngine!";
var result = Engine.Razor.RunCompile(template, "templateKey", null, new { Name = "World" });

  • Output the following
Hello World, welcome to RazorEngine!

Used hereRunCompileMethod is an extension method, and you need to reference it RazorEngine.Templating Namespace.

The “templatekey” maintains a unique value, such as using a guid value. And you can rerun the cached template based on the string key.

If you use this key again, you can use the original template.

var result = Engine.Razor.Run("templateKey", null, new { Name = "Max" });
  • The following will be output
Hello Max, welcome to RazorEngine!

The third parameter of runcompile above passes null, because the fourth parameter uses anonymous class,

The root directory creates a HelloWord.cshtml , to select an attribute, > copy content if newer,

Hello @Model.Name, welcome to RazorEngine!

The console code is as follows.

string templateFilePath = "HelloWorld.cshtml";
var templateFile = File.ReadAllText(templateFilePath);
string templateFileResult = Engine.Razor.RunCompile(templateFile, Guid.NewGuid().ToString(), null, new
    Name = "World"

  • console output
Hello World, welcome to RazorEngine!
  • Use strong type CopyRightUserInfo.cs Generate a copyright
using System;
namespace OvOv.Razor
    public class CopyRightUserInfo
        public string UserName { get; set; }
        public string EmailAddress { get; set; }
        public DateTime CreateTime { get; set; }
        public string FileRemark { get; set; }


The root directory creates a CopyRightTemplate.cshtml , to select an attribute, > copy content if newer,

    var gen = Model as OvOv.Razor.CopyRightUserInfo;
//Created by:@ gen.UserName
//Creation time:@ gen.CreateTime
//Email:@ gen.EmailAddress

The console code is as follows.

string copyRightTemplatePath = "CopyRightTemplate.cshtml";
var copyRightTemplate = File.ReadAllText(copyRightTemplatePath);
string copyRightResult = Engine.Razor.RunCompile(copyRightTemplate, Guid.NewGuid().ToString(), typeof(CopyRightUserInfo), new CopyRightUserInfo
    CreateTime = DateTime.Now,
    EmailAddress = "[email protected]",
    UserName = "IGeekFan"

  • console output
//Founder: igeekfan
//Creation time: June 23, 2020 18:14:08
//Email: [email protected]

Put it all under the console and output the following results. If the most important point of code generator is solved, we can implement our own code generator. First, we can build our own template, implement input (command line, WPF, web side and more), and output (generate file).

  • The above source code has been put into the sample code

Source code analysis

First of all, this is a console application. Main (string [] args) can receive multiple parameters.

  1. Handling no arguments, – help
  2. Process args array, resolve all parameters, if not set, the default value. The most important thing is to select the corresponding template according to – razor.
Argsrazor = // the extracted template text value according to whether - razor 1 is not 2 or the path of the template.
var razorId = Guid.NewGuid().ToString("N");
RazorEngine.Engine.Razor.Compile(ArgsRazor, razorId);
  1. According to the database connection string, take out the filtered table, view and stored procedure
  2. Table of circular database, etc,
  • Model is the data needed in the template
  • The razorid is the same as the one above,
  • SW is the value saved for the generated text.
var sw = new StringWriter();
var model = new RazorModel(fsql, ArgsNameSpace, ArgsNameOptions, tables, table);
RazorEngine.Engine.Razor.Run(razorId, sw, null, model);
  1. Save SW string to generate class. CS file (generate file name according to parameter configuration)
  2. Another one is generated__ Regenerate. Bat__ razor.cshtml.txt To facilitate subsequent users to regenerate entity classes.


This is an auxiliary toolkit derived from FreeSQL, including generator and other functions
Because this is not compatible with Mac and Linux, the author suggests using dotnet tool command line tool to generate entity classes to support MAC / Linux system. For developers who are not using FreeSQL, you can also use this tool. You only need to modify the corresponding template.

Usage: not much introduction.

  • Divided into WPF, WinForm + dskin Version (set of web pages)
  • After looking at the code, the underlying generation code logic is also used in the introduction of razorengine code generation under the razorengine. Net framework

FreeSQL official group 4336577


Recommended Today

Installation and deployment of CentOS 7

1、 Installation and configuration of virtual software virtual machine(virtual machine) refers to a complete computer system with complete hardware system functions simulated by software and running in a completely isolated environment. All the work that can be done in the real computer can be realized in the virtual machine. When creating a virtual machine in […]