FreeSql is a free, open source databases project written in C# and released under MIT. It has 4,404 GitHub stars, 910 forks and 178 open issues, and was last pushed 2 months ago. On this registry it ranks #157 of 203 tracked projects in Databases, with 5 head-to-head comparisons available.

What is FreeSql?

FreeSql is an MIT-licensed object-relational mapper for .NET, written in C# and usable from C# and VB.NET, which its maintainers describe as the first AOT ORM, and it is aimed at .NET teams that want a single data-access layer across many relational and analytical databases, including MySQL, PostgreSQL, SQL Server, Oracle, SQLite, Firebird, ClickHouse, DuckDB, TDengine, QuestDB, MsAccess and a group of Chinese domestic engines.

What it is

FreeSql lives in the .NET ecosystem and is published on NuGet, where it is listed as a member project of the .NET Core Community (NCC). It runs on .NET Core 2.1+, .NET Framework 4.0+ and Xamarin, and supports AOT compilation. The library is provider-based: each database ships as its own package, such as FreeSql.Provider.Sqlite, and the same programming model applies across all of them. Applications can adopt the core FreeSql API directly, use FreeSql.DbContext for a Repository plus UnitOfWork style, or use FreeSql.BaseEntity for a simple mode.

The concrete problem it solves is the hand-written data-access layer that a .NET application would otherwise build on top of ADO.NET, complete with per-database SQL dialects and manual mapping between rows and objects. FreeSql replaces that work with one API and one set of entity definitions, so a codebase can target several engines without maintaining separate data layers. CodeFirst data migration and DbFirst entity import move schema and entity work into the mapper itself, rather than into hand-maintained scripts and mapping code.

Key capabilities

  • CodeFirst data migration, plus DbFirst import of entity classes from an existing database or through a separate generation tool.
  • Advanced type mapping, including PostgreSQL array types.
  • Expression functions with customizable analysis.
  • One-to-many and many-to-many navigation properties, with include and lazy loading.
  • Read/write separation, table and database sharding, global filters, and optimistic and pessimistic locking.
  • Repository and Unit of Work patterns through FreeSql.DbContext, and a simple mode through FreeSql.BaseEntity, alongside AOP and dynamic operations.
  • Provider coverage spanning MySQL, SQL Server, PostgreSQL, Oracle, SQLite, Firebird, ClickHouse, DuckDB, TDengine, QuestDB, MsAccess and ODBC, as well as the domestic engines 达梦, 人大金仓, 南大通用, 虚谷, 神舟通用 and 翰高.

Who uses it and how

  • Management and administration backends, such as Zhontai.net (Admin.Core), which builds its data layer on FreeSql.
  • Content systems, such as lin-cms-dotnetcore, a CMS implemented on .NET 8.
  • Workflow platforms, such as aibpm.plus.
  • Rapid application frameworks, such as NetAdmin, based on C#12/.NET9 and FreeSql.
  • Teams that run read/write separation or split tables and databases, where the same repository code has to reach more than one provider.

Getting started

Install the provider package for the target database, for example with dotnet add package FreeSql.Provider.Sqlite, then build an IFreeSql instance through FreeSql.FreeSqlBuilder().UseConnectionString(FreeSql.DataType.Sqlite, "Data Source=document.db"). The wiki carries the getting-started guide and the Select, Insert, Update, Delete and FAQ pages.

How it compares

No comparable ORM or commercial data-access product is named in the facts supplied for this page, so FreeSql stands alone in this registry. The closest reference points the facts do provide are the applications built on it, which point to .NET application and framework development as its home ground.

When to use it — and when not to

FreeSql is a library rather than a service, so a self-hoster operates nothing beyond the target database itself, but that also means the provider choice, the migration path and the schema changes remain the adopter's responsibility. The project carries 178 open issues, its documentation lives mostly on the GitHub wiki with a number of pages available only in Chinese, and the README functions as a pointer page rather than a full manual, so teams that need a single complete English reference should plan for some reading. Teams outside .NET, or those that require a vendor commercial support agreement, are not served by what the facts describe.

project readme (upstream, from github) — read inline

🦄 FreeSql, The First AOT ORM!

FreeSql is a powerful O/RM component, supports .NET Core 2.1+, .NET Framework 4.0+, Xamarin, And AOT.

Member project of .NET Core Community nuget stats GitHub license

English | 中文

  • 🛠 Support CodeFirst data migration.
  • 💻 Support DbFirst import entity class from database, or use Generation Tool.
  • ⛳ Support advanced type mapping, such as PostgreSQL array type, etc.
  • 🌲 Support expression functions, and customizable analysis.
  • 🏁 Support one-to-many and many-to-many navigation properties, include and lazy loading.
  • 📃 Support Read/Write separation, Splitting Table/Database, Global filters, Optimistic and pessimistic locker.
  • 🌳 Support MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/人大金仓/南大通用/虚谷/神舟通用/翰高/ClickHouse/DuckDB/TDengine/QuestDB/MsAccess, etc.

QQ Groups:561616019(available)、4336577(full)、8578575(full)、52508226(full)

📚 Documentation

Get started  |  Select  |  Update  |  Insert  |  Delete  |  FAQ  
Expression  |  CodeFirst  |  DbFirst  |  Filters  |  AOP  
Repository  |  UnitOfWork  |  Dynamic Operations  |  ADO  
Read/Write  |  Splitting Table  |  Hide tech  |  Update Notes  

Please select a development mode:

Some open source projects that use FreeSql:

🚀 Quick start

dotnet add package FreeSql.Provider.Sqlite

static IFreeSql fsql = new FreeSql.FreeSqlBuilder()
  .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=document.db")
  .UseAutoSyncStructure(true) //automatically synchronize the entity structure to the database
  .Build(); //be sure to define as singleton mode

class Song {
  [Column(IsIdentity = true)]
  public int Id { get; set; }
  public string Title { get; set; }
  public string Url { get; set; }
  public DateTime CreateTime { get; set; }
  
  public ICollection<Tag> Tags { get; set; }
}
class Song_tag {
  public int Song_id { get; set; }
  public Song Song { get; set; }
  
  public int Tag_id { get; set; }
  public Tag Tag { get; set; }
}
class Tag {
  [Column(IsIdentity = true)]
  public int Id { get; set; }
  public string Name { get; set; }
  
  public int? Parent_id { get; set; }
  public Tag Parent { get; set; }
  
  public ICollection<Song> Songs { get; set; }
  public ICollection<Tag> Tags { get; set; }
}

🔎 Query

//OneToOne、ManyToOne
fsql.Select<Tag>().Where(a => a.Parent.Parent.Name == "English").ToList();

//OneToMany
fsql.Select<Tag>().IncludeMany(a => a.Tags, then => then.Where(sub => sub.Name == "foo")).ToList();

//ManyToMany
fsql.Select<Song>()
  .IncludeMany(a => a.Tags, then => then.Where(sub => sub.Name == "foo"))
  .Where(s => s.Tags.Any(t => t.Name == "Chinese"))
  .ToList();

//Other
fsql.Select<YourType>()
  .Where(a => a.IsDelete == 0)
  .WhereIf(keyword != null, a => a.UserName.Contains(keyword))
  .WhereIf(role_id > 0, a => a.RoleId == role_id)
  .Where(a => a.Nodes.Any(t => t.Parent.Id == t.UserId))
  .Count(out var total)
  .Page(page, size)
  .OrderByDescending(a => a.Id)
  .ToList()

More..

fsql.Select<Song>().Where(a => new[] { 1, 2, 3 }.Contains(a.Id)).ToList();

fsql.Select<Song>().Where(a => a.CreateTime.Date == DateTime.Today).ToList();

fsql.Select<Song>().OrderBy(a => Guid.NewGuid()).Limit(10).ToList();

fsql.Select<Song>().ToList(a => new
{
    a.Id,
    Tags = fsql.Select<Tag>().ToList(),
    SongTags = fsql.Select<SongTag>().Where(b => b.TopicId == a.Id).ToList()
});

More..

🚁 Repository

dotnet add package FreeSql.Repository

[Transactional]
public void Add() {
  var repo = ioc.GetService<BaseRepository<Tag>>();
  repo.DbContextOptions.EnableCascadeSave = true;

  var item = new Tag {
    Name = "testaddsublist",
    Tags = new[] {
      new Tag { Name = "sub1" },
      new Tag { Name = "sub2" }
    }
  };
  repo.Insert(item);
}

Reference: Use TransactionalAttribute and UnitOfWorkManager in ASP.NET Core to Achieve the Multiple Transaction Propagation.

💪 Performance

FreeSql Query & Dapper Query

Elapsed: 00:00:00.6733199; Query Entity Counts: 131072; ORM: Dapper

Elapsed: 00:00:00.4554230; Query Tuple Counts: 131072; ORM: Dapper

Elapsed: 00:00:00.6846146; Query Dynamic Counts: 131072; ORM: Dapper

Elapsed: 00:00:00.6818111; Query Entity Counts: 131072; ORM: FreeSql*

Elapsed: 00:00:00.6060042; Query Tuple Counts: 131072; ORM: FreeSql*

Elapsed: 00:00:00.4211323; Query ToList<Tuple> Counts: 131072; ORM: FreeSql*

Elapsed: 00:00:01.0236285; Query Dynamic Counts: 131072; ORM: FreeSql*

FreeSql ToList & Dapper Query

Elapsed: 00:00:00.6707125; ToList Entity Counts: 131072; ORM: FreeSql*

Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper

More..

👯 Contributors

And other friends who made important suggestions for this project, they include:

systemhejiyong, LambertW, mypeng1985, stulzq, movingsam, ALer-R, zouql, 深圳|凉茶, densen2014, LiaoLiaoWuJu, hd2y, tky753, feijie999, constantine, JohnZhou2020, mafeng8, VicBilibily, Soar, quzhen91, homejun, [d4ilys](https://github.com/d4i

readme truncated — read the full docs on github

Frequently asked questions

Is FreeSql free to use?

FreeSql is open source under the MIT licence. There is no licence fee and no seat count — you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does FreeSql do?

.NET aot orm, VB.NET/C# orm, Mysql/PostgreSQL/SqlServer/Oracle orm, Sqlite/Firebird/Clickhouse/DuckDB orm, 达梦/金仓/虚谷/翰高/高斯 orm, 神通 orm, 南大通用 orm, 国产 orm, TDengin

What is FreeSql written in?

FreeSql is primarily written in C#. Its source is publicly available at https://github.com/dotnetcore/FreeSql, and it has 4,404 GitHub stars.