FreeSql/readme.md
28810 7f3aa84ffe ## v0.3.22
- 优化 导航属性 ManyToOne 名称查找规则;
- 增加 IFreeSql.Aop 属性,未来所有拦截方法都在这里,第一期支持如下:
  * 监控 ToList 返回的的数据,用于拦截重新装饰;
  * 监视 Where,包括 select/update/delete,返回值 true 时可使上层不被执行;
  * 可自定义解析表达式;
- 增加 ISelect.TractToList,用于单次跟踪或审核实体;
- 优化 FreeSql.DbContext SaveChanges;
2019-03-22 00:26:08 +08:00

204 lines
7.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

FreeSql 是一个功能强大的 .NETStandard 库,用于对象关系映射程序(O/RM),便于开发人员能够使用 .NETStandard 对象来处理数据库,不必经常编写大部分数据访问代码。支持 .NETCore 2.1+ 或 .NETFramework 4.6.1+。
| Package Name | NuGet | Downloads |
|--------------| ------- | ---- |
| FreeSql | [![nuget](https://img.shields.io/nuget/v/FreeSql.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql) | [![stats](https://img.shields.io/nuget/dt/FreeSql.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql?groupby=Version) |
| [FreeSql.Repository](https://github.com/2881099/FreeSql/wiki/Repository) | [![nuget](https://img.shields.io/nuget/v/FreeSql.Repository.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.Repository) | [![stats](https://img.shields.io/nuget/dt/FreeSql.Repository.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.Repository?groupby=Version) |
| [FreeSql.DbContext](https://github.com/2881099/FreeSql/wiki/DbContext) | [![nuget](https://img.shields.io/nuget/v/FreeSql.DbContext.svg?style=flat-square)](https://www.nuget.org/packages/FreeSql.DbContext) | [![stats](https://img.shields.io/nuget/dt/FreeSql.DbContext.svg?style=flat-square)](https://www.nuget.org/stats/packages/FreeSql.DbContext?groupby=Version) |
# 特性
- [x] 支持 CodeFirst 迁移;
- [x] 支持 DbFirst 从数据库导入实体类,支持三种模板生成器;
- [x] 采用 ExpressionTree 高性能读取数据;
- [x] 支持深入的类型映射比如pgsql的数组类型堪称匠心制作
- [x] 支持丰富的表达式函数;
- [x] 支持导航属性查询,和延时加载;
- [x] 支持同步/异步数据库操作方法,丰富多彩的链式查询方法;
- [x] 支持读写分离、分表分库,租户设计;
- [x] 支持多种数据库MySql/SqlServer/PostgreSQL/Oracle/Sqlite
| | |
| - | - |
| 入门 | [《Select》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2) \| [《Update》](https://github.com/2881099/FreeSql/wiki/%e4%bf%ae%e6%94%b9) \| [《Insert》](https://github.com/2881099/FreeSql/wiki/%e6%b7%bb%e5%8a%a0) \| [《Delete》](https://github.com/2881099/FreeSql/wiki/%e5%88%a0%e9%99%a4) |
| 新手 | [《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0) \| [《CodeFirst》](https://github.com/2881099/FreeSql/wiki/CodeFirst) \| [《DbFirst》](https://github.com/2881099/FreeSql/wiki/DbFirst) |
| 高手 | [《Repository》](https://github.com/2881099/FreeSql/wiki/Repository) \| [《UnitOfWork》](https://github.com/2881099/FreeSql/wiki/%e5%b7%a5%e4%bd%9c%e5%8d%95%e5%85%83) \| [《过滤器》](https://github.com/2881099/FreeSql/wiki/%e8%bf%87%e6%bb%a4%e5%99%a8) \| [《DbContext》](https://github.com/2881099/FreeSql/wiki/DbContext) |
| 不朽 | [《读写分离》](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) \| [《分区分表》](https://github.com/2881099/FreeSql/wiki/%e5%88%86%e5%8c%ba%e5%88%86%e8%a1%a8) \| [《租户》](https://github.com/2881099/FreeSql/wiki/%e7%a7%9f%e6%88%b7) \| [更新日志](https://github.com/2881099/FreeSql/wiki/%e6%9b%b4%e6%96%b0%e6%97%a5%e5%bf%97) |
# Quick start
> dotnet add package FreeSql
```csharp
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
```csharp
//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 查询数据文档》](https://github.com/2881099/FreeSql/wiki/%e6%9f%a5%e8%af%a2)
# Lambda
```csharp
var t3 = f.Select<Song>.Where(a => new[] { 1, 2, 3 }.Contains(a.Id)).ToList();
```
```csharp
var t4 = select.Where(a => a.CreateTime.Date == DateTime.Now.Date).ToList();
```
```csharp
var t5 = select.OrderBy(a => Guid.NewGuid()).Limit(1).ToList();
```
更多前往Wiki[《表达式函数》](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0)
# Repository & UnitOfWork
> dotnet add package FreeSql.Repository
```csharp
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
```csharp
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
```csharp
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:
```csharp
var songRepository = fsql.GetRepository<Song, int>();
using (songRepository.DataFilter.Disable("Tenant")) {
//Tenant Invalid
}
//Tenant restore
```
# Performance
FreeSql Query & Dapper Query
```shell
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
```shell
Elapsed: 00:00:00.6707125; ToList Entity Counts: 131072; ORM: FreeSql*
Elapsed: 00:00:00.6495301; Query Entity Counts: 131072; ORM: Dapper
```
[Test code](FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs)
# Contributors
[systemhejiyong](https://github.com/systemhejiyong)
[LambertW](https://github.com/LambertW)