From 6d083642fe97c18918320503dc5cbecbe0eecd5d Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Fri, 28 Feb 2020 07:10:44 +0800 Subject: [PATCH] update --- Home.md | 2 +- Repository.md | 4 +- _Sidebar.md | 4 +- 事务.md | 112 ++++++++++++++++++++++++++++++++++---------------- 工作单元.md | 4 +- 更新日志.md | 2 +- 6 files changed, 86 insertions(+), 42 deletions(-) diff --git a/Home.md b/Home.md index c2aec09..6d4b9bf 100644 --- a/Home.md +++ b/Home.md @@ -48,7 +48,7 @@ FreeSql是一个功能强大的NETStandard库,用于对象关系映射程序(O * [字符串](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0#%e5%ad%97%e7%ac%a6%e4%b8%b2) * [日期/时间](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0#%e6%97%a5%e6%9c%9f) * [其他](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0#%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0%e5%85%a8%e8%a7%88) - * [自定义函数](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0#%E8%87%AA%E5%AE%9A%E4%B9%89%E8%A1%A8%E8%BE%BE%E5%BC%8F%E5%87%BD%E6%95%B0v01123) + * [自定义函数](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0#%E8%87%AA%E5%AE%9A%E4%B9%89%E8%A7%A3%E6%9E%90) * [事务](https://github.com/2881099/FreeSql/wiki/%e4%ba%8b%e5%8a%a1) * [AOP!!](https://github.com/2881099/FreeSql/wiki/AOP) * [读写分离](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) diff --git a/Repository.md b/Repository.md index e04ab3d..9e4f331 100644 --- a/Repository.md +++ b/Repository.md @@ -126,8 +126,8 @@ UnitOfWork 可将多个仓储放在一个单元管理执行,最终通用 Commi ```csharp using (var uow = fsql.CreateUnitOfWork()) { - var songRepos = uow.GetRepository(); - var userRepos = uow.GetRepository(); + var songRepo = uow.GetRepository(); + var userRepo = uow.GetRepository(); //上面两个仓储,由同一UnitOfWork uow 创建 //在此执行仓储操作 diff --git a/_Sidebar.md b/_Sidebar.md index 6181ecb..bff0876 100644 --- a/_Sidebar.md +++ b/_Sidebar.md @@ -36,7 +36,9 @@ * [字符串](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0#%e5%ad%97%e7%ac%a6%e4%b8%b2) * [日期/时间](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0#%e6%97%a5%e6%9c%9f) * [其他](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0#%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0%e5%85%a8%e8%a7%88) - * [自定义函数](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0#%E8%87%AA%E5%AE%9A%E4%B9%89%E8%A1%A8%E8%BE%BE%E5%BC%8F%E5%87%BD%E6%95%B0v01123) + * [自定义函数](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0#%E8%87%AA%E5%AE%9A%E4%B9%89%E8%A7%A3%E6%9E%90) + + https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0#%E8%87%AA%E5%AE%9A%E4%B9%89%E8%A7%A3%E6%9E%90 * [事务](https://github.com/2881099/FreeSql/wiki/%e4%ba%8b%e5%8a%a1) * [AOP!!](https://github.com/2881099/FreeSql/wiki/AOP) * [读写分离](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb) diff --git a/事务.md b/事务.md index da1e220..6ddd1c3 100644 --- a/事务.md +++ b/事务.md @@ -1,6 +1,6 @@ -FreeSql提供了四种数据库事务的使用方法。 +FreeSql 提供了四种数据库事务的使用说明。 -## 外部事务 +## 1、外部事务 适合在外部开启事务的场景,FreeSql CRUD 提供了 WithTransaction 传入事务对象。 @@ -13,7 +13,7 @@ fsql.Update() ISelect、IInsert、IUpdate、IDelete,都支持 WithTransaction 方法。 -## 同线程事务 +## 2、同线程事务 假设用户购买了价值100元的商品: @@ -26,26 +26,26 @@ ISelect、IInsert、IUpdate、IDelete,都支持 WithTransaction 方法。 ```csharp fsql.Transaction(() => { - //fsql.Ado.TransactionCurrentThread 此属性可得到事务对象 + //fsql.Ado.TransactionCurrentThread 此属性可得到事务对象 - var affrows = fsql.Update().Set(a => a.Wealth - 100) - .Where(a => a.Wealth >= 100) - //判断别让用户余额扣成负数 - .ExecuteAffrows(); - if (affrows < 1) - throw new Exception("用户余额不足"); - //抛出异常,事务退出 + var affrows = fsql.Update().Set(a => a.Wealth - 100) + .Where(a => a.Wealth >= 100) + //判断别让用户余额扣成负数 + .ExecuteAffrows(); + if (affrows < 1) + throw new Exception("用户余额不足"); + //抛出异常,事务退出 - affrows = fsql.Update().Set(a => a.Stock - 1) - .Where(a => a.Stock > 0) - //判断别让用库存扣成负数 - .ExecuteAffrows(); - if (affrows < 1) - throw new Exception("商品库存不足"); - //抛出异常,回滚事务,事务退出 - //用户余额的扣除将不生效 + affrows = fsql.Update().Set(a => a.Stock - 1) + .Where(a => a.Stock > 0) + //判断别让用库存扣成负数 + .ExecuteAffrows(); + if (affrows < 1) + throw new Exception("商品库存不足"); + //抛出异常,回滚事务,事务退出 + //用户余额的扣除将不生效 - //程序执行在此处,说明都扣成功了,事务完成并提交 + //程序执行在此处,说明都扣成功了,事务完成并提交 }); ``` @@ -57,38 +57,80 @@ fsql.Transaction(() => { 3、fsql.Transaction 有防止死锁机制,60秒事务未结束的,将会被其他线程强行提交(不是回滚),可能造成不完整的事务,但仔细一想60秒还没完成的事务是什么原因呢?如果嫌60秒太少了可以在重载方法的参数中设置; -## UnitOfWork + Repository +## 3、UnitOfWork + Repository UnitOfWork 可将多个仓储放在一个单元管理执行,最终通用 Commit 执行所有操作,内部采用了数据库事务; ```csharp using (var uow = fsql.CreateUnitOfWork()) { - var songRepos = uow.GetRepository(); - var userRepos = uow.GetRepository(); + var songRepo = uow.GetRepository(); + var userRepo = uow.GetRepository(); - //上面两个仓储,由同一UnitOfWork uow 创建 - //在此执行仓储操作 - - //这里不受异步方便影响 + //上面两个仓储,由同一UnitOfWork uow 创建 + //在此执行仓储操作 + + //这里不受异步方便影响 - uow.Commit(); + uow.Commit(); } ``` -## DbContext +参考:在 asp.net core 中注入工作单元方法 + +```csharp +//第一步: +public class UnitOfWorkRepository : BaseRepository +{ + public UnitOfWorkRepository(IFreeSql fsql, IUnitOfWork uow) : base(fsql, null, null) + { + this.UnitOfWork = uow; + } +} +public class UnitOfWorkRepository : BaseRepository +{ + public UnitOfWorkRepository(IFreeSql fsql, IUnitOfWork uow) : base(fsql, null, null) + { + this.UnitOfWork = uow; + } +} + +//第二步: +public void ConfigureServices(IServiceCollection services) +{ + services.AddSingleton(fsql); + services.AddScoped(sp => fsql.CreateUnitOfWork()); + + services.AddScoped(typeof(IReadOnlyRepository<>), typeof(UnitOfWorkRepository<>)); + services.AddScoped(typeof(IBasicRepository<>), typeof(UnitOfWorkRepository<>)); + services.AddScoped(typeof(BaseRepository<>), typeof(UnitOfWorkRepository<>)); + + services.AddScoped(typeof(IReadOnlyRepository<,>), typeof(UnitOfWorkRepository<,>)); + services.AddScoped(typeof(IBasicRepository<,>), typeof(UnitOfWorkRepository<,>)); + services.AddScoped(typeof(BaseRepository<,>), typeof(UnitOfWorkRepository<,>)); + + //批量注入程序集内的所有自建仓储类,可以根据自己需要来修改 + Assembly[] assemblies = new [] { typeof(XxxRepository).Assembly }; + if (assemblies?.Any() == true) + foreach (var asse in assemblies) + foreach (var repo in asse.GetTypes().Where(a => a.IsAbstract == false && typeof(UnitOfWorkRepository).IsAssignableFrom(a))) + services.AddScoped(repo); +} +``` + +## 4、DbContext ```csharp using (var ctx = fsql.CreateDbContext()) { - var song = ctx.Set(); - var user = ctx.Set(); - - //这里不受异步方便影响 + var song = ctx.Set(); + var user = ctx.Set(); + + //这里不受异步方便影响 - ctx.SaveChanges(); + ctx.SaveChanges(); } ``` -## 更新排他锁 +## 5、更新排他锁 ```csharp var user = fsql.Select().ForUpdate(true).Where(a => a.Id == 1).ToOne(); diff --git a/工作单元.md b/工作单元.md index 908636e..0a1f11b 100644 --- a/工作单元.md +++ b/工作单元.md @@ -16,8 +16,8 @@ static IFreeSql fsql = new FreeSql.FreeSqlBuilder() ```csharp using (var uow = fsql.CreateUnitOfWork()) { - var songRepos = uow.GetRepository(); - var userRepos = uow.GetRepository(); + var songRepo = uow.GetRepository(); + var userRepo = uow.GetRepository(); //上面两个仓储,由同一UnitOfWork uow 创建 diff --git a/更新日志.md b/更新日志.md index 3aa46df..e82a42c 100644 --- a/更新日志.md +++ b/更新日志.md @@ -152,7 +152,7 @@ ## v0.11.23 -- 增加 ExpressionCallAttribute 特性,实现表达式函数自定义解析;[wiki](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0#%E8%87%AA%E5%AE%9A%E4%B9%89%E8%A1%A8%E8%BE%BE%E5%BC%8F%E5%87%BD%E6%95%B0v01123) +- 增加 ExpressionCallAttribute 特性,实现表达式函数自定义解析;[wiki](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0#%E8%87%AA%E5%AE%9A%E4%B9%89%E8%A7%A3%E6%9E%90) - 优化 Contains 表达式解析为 where in 自动拆分,防止大于 1000 的 SQL 错误,如下: ```csharp var arr = Enumerable.Range(1, 1333).ToArray();