mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-20 17:52:51 +08:00

- 优化 导航属性 ManyToOne 名称查找规则; - 增加 IFreeSql.Aop 属性,未来所有拦截方法都在这里,第一期支持如下: * 监控 ToList 返回的的数据,用于拦截重新装饰; * 监视 Where,包括 select/update/delete,返回值 true 时可使上层不被执行; * 可自定义解析表达式; - 增加 ISelect.TractToList,用于单次跟踪或审核实体; - 优化 FreeSql.DbContext SaveChanges;
7.8 KiB
7.8 KiB
FreeSql 是一个功能强大的 .NETStandard 库,用于对象关系映射程序(O/RM),便于开发人员能够使用 .NETStandard 对象来处理数据库,不必经常编写大部分数据访问代码。支持 .NETCore 2.1+ 或 .NETFramework 4.6.1+。
Package Name | NuGet | Downloads |
---|---|---|
FreeSql | ||
FreeSql.Repository | ||
FreeSql.DbContext |
特性
- 支持 CodeFirst 迁移;
- 支持 DbFirst 从数据库导入实体类,支持三种模板生成器;
- 采用 ExpressionTree 高性能读取数据;
- 支持深入的类型映射,比如pgsql的数组类型,堪称匠心制作;
- 支持丰富的表达式函数;
- 支持导航属性查询,和延时加载;
- 支持同步/异步数据库操作方法,丰富多彩的链式查询方法;
- 支持读写分离、分表分库,租户设计;
- 支持多种数据库,MySql/SqlServer/PostgreSQL/Oracle/Sqlite;
入门 | 《Select》 | 《Update》 | 《Insert》 | 《Delete》 |
新手 | 《表达式函数》 | 《CodeFirst》 | 《DbFirst》 |
高手 | 《Repository》 | 《UnitOfWork》 | 《过滤器》 | 《DbContext》 |
不朽 | 《读写分离》 | 《分区分表》 | 《租户》 | 更新日志 |
Quick start
dotnet add package FreeSql
IFreeSql fsql = new FreeSql.FreeSqlBuilder()
.UseConnectionString(FreeSql.DataType.MySql, "connectionString")
.UseAutoSyncStructure(true) //自动同步实体结构到数据库
.Build();
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 virtual ICollection<Tag> Tags { get; set; }
}
class Song_tag {
public int Song_id { get; set; }
public virtual Song Song { get; set; }
public int Tag_id { get; set; }
public virtual 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 virtual Tag Parent { get; set; }
public virtual ICollection<Song> Songs { get; set; }
public virtual ICollection<Tag> Tags { get; set; }
}
Query
//OneToOne、ManyToOne
var t0 = fsql.Select<Tag>().Where(a => a.Parent.Parent.Name == "粤语").ToList();
//OneToMany
var t1 = fsql.Select<Tag>().Where(a => a.Tags.AsSelect().Any(t => t.Parent.Id == 10)).ToList();
//ManyToMany
var t2 = fsql.Select<Song>().Where(s => s.Tags.AsSelect().Any(t => t.Name == "国语")).ToList();
更多前往Wiki:《Select 查询数据文档》
Lambda
var t3 = f.Select<Song>.Where(a => new[] { 1, 2, 3 }.Contains(a.Id)).ToList();
var t4 = select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList();
var t5 = select.OrderBy(a => Guid.NewGuid()).Limit(1).ToList();
更多前往Wiki:《表达式函数》
Repository & UnitOfWork
dotnet add package FreeSql.Repository
using (var unitOfWork = fsql.CreateUnitOfWork()) {
var songRepository = uow.GetRepository<Song, int>();
var tagRepository = uow.GetRepository<Tag, int>();
await songRepository.InsertAsync(new Song());
await tagRepository.InsertAsync(new Tag());
uow.Commit();
}
DbContext & DbSet
dotnet add package FreeSql.DbContext
public class SongContext : DbContext {
public DbSet<Song> Songs { get; set; }
public DbSet<Song> Tags { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder builder) {
builder.UseFreeSql(fsql);
}
}
long id = 0;
using (var ctx = new SongContext()) {
var song = new Song { };
await ctx.Songs.AddAsync(song);
id = song.Id;
var adds = Enumerable.Range(0, 100).Select(a => new Song { Title = "xxxx" + a, Url = "url222" }).ToList();
await ctx.Songs.AddRangeAsync(adds);
for (var a = 0; a < adds.Count; a++)
adds[a].Title = "dkdkdkdk" + a;
ctx.Songs.UpdateRange(adds);
ctx.Songs.RemoveRange(adds.Skip(10).Take(20).ToList());
ctx.Songs.Update(adds.Last());
await ctx.SaveChangesAsync();
}
DataFilter & Tenant
public IServiceProvider ConfigureServices(IServiceCollection services) {
services.AddSingleton<IFreeSql>(fsql);
services.AddMvc();
var builder = new ContainerBuilder();
builder.RegisterFreeRepository(filter => filter
.Apply<ISoftDelete>("SoftDelete", a => a.IsDeleted == false)
.Apply<ITenant>("Tenant", a => a.TenantId == 1)
);
builder.Populate(services);
var container = builder.Build();
return new AutofacServiceProvider(container);
}
Temporary disable:
var songRepository = fsql.GetRepository<Song, int>();
using (songRepository.DataFilter.Disable("Tenant")) {
//Tenant Invalid
}
//Tenant restore
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