Skip to content

Commit

Permalink
优化文档
Browse files Browse the repository at this point in the history
  • Loading branch information
2881099 committed Jul 24, 2024
1 parent 25f8e57 commit e968f4e
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 112 deletions.
10 changes: 5 additions & 5 deletions docs/.vuepress/sidebar/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ export const zhSidebarConfig = sidebar({
"lowcode",
],
},
"expression-function",
"transaction",
"filters",
"ado",
"aop",
{
text: "CodeFirst",
collapsible: true,
Expand All @@ -89,11 +94,6 @@ export const zhSidebarConfig = sidebar({
],
},
"db-first",
"expression-function",
"transaction",
"filters",
"ado",
"aop",
"more",
{
text: "高级功能",
Expand Down
107 changes: 23 additions & 84 deletions docs/guide/repository.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,31 @@ tag:
- Repository
---

`FreeSql.Repository` 实现了通用仓储层功能。FreeSql.Repository 参考 abp vnext 接口规范,实现仓储层(CURD)。
`FreeSql` 实现了通用仓储层功能。FreeSql.DbContext 参考 abp vnext 接口规范,实现仓储层(CURD)。

## 特性

- Select/Attach 快照对象,Update 只更新变化的字段;
- Insert 插入数据,适配各数据库优化执行 ExecuteAffrows/ExecuteIdentity/ExecuteInserted;
- InsertOrUpdate 插入或更新;
- SaveMany 方法快速保存导航对象(一对多、多对多);

## 安装

::: code-tabs

@tab:active .NET CLI

```bash
dotnet add package FreeSql.Repository
dotnet add package FreeSql.DbContext
```

@tab .NET Framework

```bash
Install-Package FreeSql.Repository
Install-Package FreeSql.DbContext
```

:::

## 定义
- Select/Attach 快照对象,Update 只更新变化的字段;
- Insert 插入数据,适配各数据库优化执行 ExecuteAffrows/ExecuteIdentity/ExecuteInserted;
- 级联保存、级联删除(一对一、一对多、多对多);
- 仓储 + 工作单元设计模式,风格简洁、统一;

```csharp
static IFreeSql fsql = new FreeSql.FreeSqlBuilder()
.UseConnectionString(FreeSql.DataType.Sqlite, connectionString)
.UseAutoSyncStructure(true) //自动迁移实体的结构到数据库
.Build(); //请务必定义成 Singleton 单例模式
public class Song
{
[Column(IsIdentity = true)]
Expand All @@ -47,63 +37,50 @@ public class Song
}
```

## 使用方法
> 注意:Repository 对象多线程不安全,因此不应在多个线程上同时对其执行工作。
方法 1、IFreeSql 的扩展方法;
## 临时用法

```csharp
var curd = fsql.GetRepository<Song>();
```

> 注意:Repository 对象多线程不安全,因此不应在多个线程上同时对其执行工作
> 适合在局部代码中,临时的创建仓储,用完就扔掉了
- 不支持从不同的线程同时使用同一仓储实例
- 通过GetRepository相当于直接new DefaultRepository<TEntity, int>,每次调用都会创建一个新的实例,.NET Core中不建议使用
## 泛型仓储(依赖注入)

方法 2、泛型仓储+依赖注入(.NET Core);

```csharp
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IFreeSql>(fsql);
services.AddFreeRepository(null);
}
//先看入门文档注入 IFreeSql
services.AddFreeRepository();

//在控制器使用泛型仓储
public SongsController(IBaseRepository<Song> songRepository)
{
}
```

方法 3、继承泛型仓储+依赖注入(.NET Core);
## 继承仓储(依赖注入)

```csharp
public class SongRepository : BaseRepository<Song, int>
{
public SongRepository(IFreeSql fsql) : base(fsql, null, null) {}
//先看入门文档注入 IFreeSql
services.AddFreeRepository(typeof(SongRepository).Assembly); //如果没有继承的仓储,第二个参数不用传
//在这里增加 CURD 以外的方法
}

//注入服务
public void ConfigureServices(IServiceCollection services)
//使用继承的仓储
public SongsController(SongRepository repo1, TopicRepository repo2)
{
services.AddSingleton<IFreeSql>(fsql);
services.AddFreeRepository(null, typeof(SongRepository).Assembly); //如果没有继承的仓储,第二个参数不用传
}

//使用继承的仓储
public SongsController(SongRepository songRepository)
public class SongRepository : BaseRepository<Song>
{
}
public SongRepository(IFreeSql fsql) : base(fsql) {}

//在这里增加 CURD 以外的方法
}
```

> 依赖注入的方式可实现全局【过滤与验证】的设定,方便租户功能的设计;
更多资料:[《过滤器、全局过滤器》](filters.md)

## 状态管理
## 对比更新

只更新变化的属性:

Expand Down Expand Up @@ -185,42 +162,6 @@ class MyRepositoryOptions
}
```

## 过滤与验证

假设我们有 User(用户)、Topic(主题)两个实体,定义了两个仓储:

```csharp
var userRepository = fsql.GetRepository<User>();
var topicRepository = fsql.GetRepository<Topic>();
```

在开发过程中,总是担心 topicRepository 的数据安全问题,即有可能查询或操作到其他用户的主题。因此我们在 v0.0.7 版本增加了 filter lambda 表达式参数。

```csharp
var userRepository = fsql.GetRepository<User>(a => a.Id == 1);
var topicRepository = fsql.GetRepository<Topic>(a => a.UserId == 1);
```

- 在查询/修改/删除时附加此条件,从而达到不会修改其他用户的数据;
- 在添加时,使用表达式验证数据的合法性,若不合法则抛出异常;

## 分表与分库

FreeSql 提供 AsTable 分表的基础方法,GuidRepository 作为分存式仓储将实现了分表与分库(不支持跨服务器分库)的封装。

```csharp
var logRepository = fsql.GetGuidRepository<Log>(null, oldname => $"{oldname}_{DateTime.Now.ToString("YYYYMM")}");
```

上面我们得到一个日志仓储按年月分表,使用它 CURD 最终会操作 Log_201903 表。

注意事项:

- v0.11.12 以后的版本可以使用 CodeFirst 迁移分表;
- 不可在分表分库的实体类型中使用《延时加载》;

更多请移步[《分表分库》](sharding.md)

## 兼容问题

SqlServer 提供的 output inserted 特性,在表使用了自增或数据库定义了默认值的时候,使用它可以快速将 insert 的数据返回。PostgreSQL 也有相应的功能,如此方便但不是每个数据库都支持。
Expand All @@ -242,7 +183,6 @@ SqlServer 提供的 output inserted 特性,在表使用了自增或数据库
| UnitOfWork | IUnitOfWork | 正在使用的工作单元 |
| Orm | IFreeSql | 正在使用的 Orm |
| DbContextOptions | DbContextOptions | 正在使用的 DbContext 设置,修改设置不影响其他 |
| DataFilter | IDataFilter\<TEntity\> | 仓储过滤器,本对象内生效 |
| UpdateDiy | IUpdate\<TEntity\> | 准备更新数据,与仓储同事务 |
| Select | ISelect\<TEntity\> | 准备查询数据 |

Expand All @@ -265,7 +205,6 @@ SqlServer 提供的 output inserted 特性,在表使用了自增或数据库
| Attach | - | TEntity | 附加实体到状态管理,可用于不查询就更新或删除 |
| Attach | - | IEnumerable\<TEntity\> | 批量附加实体到状态管理 |
| AttachOnlyPrimary | - | TEntity | 只附加实体的主键数据到状态管理 |
| [SaveMany](cascade-saving.html) | - | TEntity, string | 保存实体的指定 ManyToMany/OneToMany 导航属性(完整对比) |
| [BeginEdit](insert-or-update.html#_5%E3%80%81beginedit-%E6%89%B9%E9%87%8F%E7%BC%96%E8%BE%91) | - | List\<TEntity\> | 准备编辑一个 List 实体 |
| EndEdit | int || 完成编辑数据,进行保存动作 |

Expand Down
5 changes: 5 additions & 0 deletions docs/guide/transaction.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,15 @@ using (var uow = fsql.CreateUnitOfWork())

await fsql.Insert(item)... //错误,不在一个事务
var repo = uow.GetRepository<Song>(); //仓储 CRUD
await repo.InsertAsync(item);

uow.Commit();
}
```

> 提示:uow 范围内,尽量别使用 fsql 对象,以免不处在一个事务
## 2、仓储事务(依赖注入)

```csharp
Expand Down
41 changes: 18 additions & 23 deletions docs/guide/unit-of-work.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,27 @@
# UnitOfWork

UnitOfWork 可将多个仓储放在一个单元管理执行,最终通用 Commit 执行所有操作,内部使用了数据库事务;

```csharp
var connstr = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;" +
"Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10";

static IFreeSql fsql = new FreeSql.FreeSqlBuilder()
.UseConnectionString(FreeSql.DataType.MySql, connstr)
.UseAutoSyncStructure(true) //自动同步实体结构到数据库
.Build(); //请务必定义成 Singleton 单例模式
```
UnitOfWork 是对 DbTransaction 事务对象的封装,可以方便夹带私有数据。

## 如何使用

```csharp
using (var uow = fsql.CreateUnitOfWork())
{
var songRepo = fsql.GetRepository<Song>();
songRepo.UnitOfWork = uow;
var userRepo = fsql.GetRepository<User>();
userRepo.UnitOfWork = uow;
await uow.Orm.Insert(item).ExecuteAffrowsAsync(); //uow.Orm API 和 IFreeSql 一样
await uow.Orm.Ado.ExecuteNoneQueryAsync(sql);

await fsql.Insert(item)... //错误,不在一个事务
songRepo.Insert(new Song());
userRepo.Update(...);
var repo1 = uow.GetRepository<Song>();
await repo1.InsertAsync(item);

uow.Commit();
}
```

参考:[在 asp.net core 中使用 TransactionalAttribute + UnitOfWorkManager 实现多种事务传播](unitofwork-manager.md)
> 提示:uow 范围内,尽量别使用 fsql 对象,以免不处在一个事务
依赖注入(参考):[在 asp.net core 中使用 TransactionalAttribute + UnitOfWorkManager 实现多种事务传播](unitofwork-manager.md)

## 接口定义

Expand Down Expand Up @@ -78,16 +70,19 @@ fsql.SetDbContextOptions(opt => {
单独设置:

```csharp
var uow = fsql.CreateUnitOfWork();
uow.OnEntityChange = report => {
Console.WriteLine(report);
};
using (var uow = fsql.CreateUnitOfWork())
{
uow.OnEntityChange = report => {
Console.WriteLine(report);
};
}
```

参数 report 是一个 List 集合,集合元素的类型定义如下:

```csharp
public class ChangeInfo {
public class ChangeInfo
{
public object Object { get; set; }
public EntityChangeType Type { get; set; }
/// <summary>
Expand Down

0 comments on commit e968f4e

Please sign in to comment.