using Admin.NET.Core.Service; using Admin.NET.Application.Entity; using Microsoft.AspNetCore.Http; using Furion.DatabaseAccessor; using Yitter.IdGenerator; namespace Admin.NET.Application.Service.CodeExamples; /// /// 代码示例服务 /// [ApiDescriptionSettings(ApplicationConst.CodeExamplesGroupName, Order = 100)] public class CodeExamplesService : IDynamicApiController, ITransient { private readonly SqlSugarRepository _rep; private readonly SqlSugarRepository _repTeacher; private readonly SqlSugarRepository _rep_v_students; private readonly IUnitOfWork _unitOfWork; //private readonly SqlSugarUnitOfWork sugarUnitOfWork; public CodeExamplesService(SqlSugarRepository rep, IUnitOfWork unitOfWork, SqlSugarRepository repTeacher, SqlSugarRepository rep_v_students) { _rep = rep; _unitOfWork = unitOfWork; _repTeacher = repTeacher; _rep_v_students = rep_v_students; } /// /// 分页查询测试学生视图 /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "PageStudentView")] [Description("CodeExamples/PageStudentView")] public async Task> PageStudentView(TestStudentInput input) { var query = _rep_v_students.AsQueryable() .WhereIF(!string.IsNullOrWhiteSpace(input.SearchKey), u => u.Name.Contains(input.SearchKey.Trim()) || u.AliName.Contains(input.SearchKey.Trim()) ) .WhereIF(!string.IsNullOrWhiteSpace(input.Name), u => u.Name.Contains(input.Name.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.AliName), u => u.AliName.Contains(input.AliName.Trim())) .WhereIF(input.Age > 0, u => u.Age == input.Age) .WhereIF(input.NianJi > 0, u => u.NianJi == input.NianJi) .WhereIF(input.TeacherId > 0, u => u.TeacherId == input.TeacherId) .WhereIF(input.RectorId > 0, u => u.RectorId == input.RectorId) .WhereIF(input.IsInSchool.HasValue, u => u.IsInSchool == input.IsInSchool) .WhereIF(input.IsWDR.HasValue, u => u.IsWDR == input.IsWDR) .WhereIF(input.Gender.HasValue, u => u.Gender == input.Gender) .WhereIF(input.OtherGender.HasValue, u => u.OtherGender == input.OtherGender) .Select(); if (input.BrithDateRange != null && input.BrithDateRange.Count > 0) { DateTime? start = input.BrithDateRange[0].Value.AddDays(-1); query = query.WhereIF(start.HasValue, u => u.BrithDate > start); if (input.BrithDateRange.Count > 1 && input.BrithDateRange[1].HasValue) { var end = input.BrithDateRange[1].Value.AddDays(1); query = query.Where(u => u.BrithDate < end); } } if (input.InSchoolDateRange != null && input.InSchoolDateRange.Count > 0) { DateTime? start = input.InSchoolDateRange[0].Value.AddDays(-1); query = query.WhereIF(start.HasValue, u => u.InSchoolDate > start); if (input.InSchoolDateRange.Count > 1 && input.InSchoolDateRange[1].HasValue) { var end = input.InSchoolDateRange[1].Value.AddDays(1); query = query.Where(u => u.InSchoolDate < end); } } return await query.OrderBuilder(input).ToPagedListAsync(input.Page, input.PageSize); } /// /// 数据跟踪 /// /// /// [HttpGet] [ApiDescriptionSettings(Name = "GenZong")] [Description("CodeExamples/GenZong")] public async Task GenZong() { //结论:sqlsugar没有ef跟踪的概念。 var list = await _rep.AsQueryable().ToListAsync(); if (list != null && list.Count > 0) { var first = list.First(); first.Name = "我要改变值了"; var aaa = await _rep.GetFirstAsync(u => u.Id == first.Id); //结果:aaa.Name还是数据库的值,不是新改的值,即 first和aaa不是一个对象 var zz = ""; } return null; } /// /// 正常---无事务 【无事务控制,不推荐】 /// /// [HttpPost] [ApiDescriptionSettings(Name = "NoTransDemo1")] [Description("CodeExamples/NoTransDemo1")] public async Task NoTransDemo1() { await Commomn("", "正常---无事务"); return 1; } /// /// 正常---特性事务 【正确写法】【正确】 /// /// [HttpPost] [ApiDescriptionSettings(Name = "NormalTransDemo1")] [Description("CodeExamples/NormalTransDemo1")] [UnitOfWork] public async Task NormalTransDemo1() { await Commomn("", "正常---特性事务"); return 1; } /// /// 正常---手写事务 【正确写法】【正确】 /// /// [HttpPost] [ApiDescriptionSettings(Name = "NormalTransDemo12")] [Description("CodeExamples/NormalTransDemo12")] public async Task NormalTransDemo12() { var _trans = _rep.AsTenant(); try { await _trans.BeginTranAsync(); await Commomn("", "正常---手写事务"); await _trans.CommitTranAsync(); } catch { await _trans.RollbackTranAsync(); throw; } return 1; } /// /// 正常---手写事务,tran对象不一样 【正确写法】【正确】 /// /// [HttpPost] [ApiDescriptionSettings(Name = "NormalTransDemo122")] [Description("CodeExamples/NormalTransDemo122")] public async Task NormalTransDemo122() { var _trans = _rep.AsTenant(); try { await _trans.BeginTranAsync(); await Commomn("", "正常---手写事务"); await _repTeacher.AsTenant().CommitTranAsync(); } catch { await _repTeacher.AsTenant().RollbackTranAsync(); throw; } return 1; } /// /// 异常---无事务-未保存就抛异常 /// /// [HttpPost] [ApiDescriptionSettings(Name = "ExceptionTransDemo21")] [Description("CodeExamples/ExceptionTransDemo21")] public async Task ExceptionTransDemo21() { await Commomn("未保存就抛异常", "异常---无事务-未保存就抛异常"); return 1; } /// /// 异常---无事务-保存第一个就抛异常 /// /// [HttpPost] [ApiDescriptionSettings(Name = "ExceptionTransDemo22")] [Description("CodeExamples/ExceptionTransDemo22")] public async Task ExceptionTransDemo22() { //现象:老师表增加了数据,学生表没增加数据 await Commomn("保存第一个就抛异常", "异常---无事务-保存第一个就抛异常"); return 1; } /// /// 异常---无事务-保存第二个就抛异常 /// /// [HttpPost] [ApiDescriptionSettings(Name = "ExceptionTransDemo23")] [Description("CodeExamples/ExceptionTransDemo23")] public async Task ExceptionTransDemo23() { //现象:老师表和学生表都增加了数据 await Commomn("保存第二个就抛异常", "异常---无事务-保存第二个就抛异常"); return 1; } /// /// 异常---特性事务-未保存就抛异常 【正确写法】【正确】 /// /// [HttpPost] [ApiDescriptionSettings(Name = "ExceptionTransDemo1")] [Description("CodeExamples/ExceptionTransDemo1")] [UnitOfWork] public async Task ExceptionTransDemo1() { await Commomn("未保存就抛异常", "异常---特性事务-未保存就抛异常"); return 1; } /// /// 异常---特性事务-保存第一个就抛异常 【正确写法】【正确】 /// /// [HttpPost] [ApiDescriptionSettings(Name = "ExceptionTransDemo2")] [Description("CodeExamples/ExceptionTransDemo2")] [UnitOfWork] public async Task ExceptionTransDemo2() { await Commomn("保存第一个就抛异常", "异常---特性事务-保存第一个就抛异常"); return 1; } /// /// 异常---特性事务-保存第二个就抛异常 【正确写法】【正确】 /// /// [HttpPost] [ApiDescriptionSettings(Name = "ExceptionTransDemo3")] [Description("CodeExamples/ExceptionTransDemo3")] [UnitOfWork] public async Task ExceptionTransDemo3() { //Thread.Sleep(10 * 1000); await Commomn("保存第二个就抛异常", "异常---特性事务-保存第二个就抛异常"); return 1; } /// /// 异常---手写事务-未保存就抛异常 【没有影响表】【正确】 /// /// [HttpPost] [ApiDescriptionSettings(Name = "ExceptionTransDemo11")] [Description("CodeExamples/ExceptionTransDemo11")] public async Task ExceptionTransDemo11() { //现象:无影响,没有影响表 _rep.AsSugarClient().AsTenant().BeginTran(); await Commomn("未保存就抛异常", "异常---手写事务-未保存就抛异常"); _rep.AsSugarClient().AsTenant().CommitTran(); return 1; } #region 异常---手写事务-保存第一个就抛异常 /// /// 异常---手写事务-保存第一个就抛异常 【没写RollbackTranAsync】【异常】 /// /// [HttpPost] [ApiDescriptionSettings(Name = "ExceptionTransDemo12")] [Description("CodeExamples/ExceptionTransDemo12")] public async Task ExceptionTransDemo12() { //没写RollbackTranAsync //现象:老师表会锁表,学生表不会锁 await _rep.AsTenant().BeginTranAsync(); await Commomn("保存第一个就抛异常", "异常---手写事务-保存第一个就抛异常"); await _rep.AsTenant().CommitTranAsync(); return 1; } /// /// 异常---手写事务-保存第一个就抛异常 【没写BeginTranAsync】【异常】 /// /// [HttpPost] [ApiDescriptionSettings(Name = "ExceptionTransDemo1287")] [Description("CodeExamples/ExceptionTransDemo1287")] public async Task ExceptionTransDemo1287() { // 没写 BeginTranAsync //现象:老师表数据写进去了,学生表没有写进去,没有锁表,事务没有回滚 try { await Commomn("保存第一个就抛异常", "异常---手写事务-保存第一个就抛异常"); await _rep.AsTenant().CommitTranAsync(); return 1; } catch { await _rep.AsTenant().RollbackTranAsync(); throw; } //*/ } /// /// 异常---手写事务-保存第一个就抛异常 【正确写法】【正确】 /// /// [HttpPost] [ApiDescriptionSettings(Name = "ExceptionTransDemo999")] [Description("CodeExamples/ExceptionTransDemo999")] public async Task ExceptionTransDemo999() { // 正确写法 //现象:正常报错,没有锁表,事务回滚 try { await _rep.AsTenant().BeginTranAsync(); await Commomn("保存第一个就抛异常", "异常---手写事务-保存第一个就抛异常"); await _rep.AsTenant().CommitTranAsync(); return 1; } catch { await _rep.AsTenant().RollbackTranAsync(); throw; } //*/ } #endregion #region 异常---手写事务-保存第二个就抛异常 /// /// 异常---手写事务-保存第二个就抛异常 【没写RollbackTran】【异常】 /// /// [HttpPost] [ApiDescriptionSettings(Name = "ExceptionTransDemo13")] [Description("CodeExamples/ExceptionTransDemo13")] public async Task ExceptionTransDemo13() { //没写RollbackTran //现象:老师表和学生表都会锁表 await _rep.AsTenant().BeginTranAsync(); await Commomn("保存第二个就抛异常", "异常---手写事务-保存第二个就抛异常"); await _rep.AsTenant().CommitTranAsync(); return 1; //*/ } /// /// 异常---手写事务-保存第二个就抛异常 【没写BeginTranAsync】【异常】 /// /// [HttpPost] [ApiDescriptionSettings(Name = "ExceptionTransDemo1213")] [Description("CodeExamples/ExceptionTransDemo1213")] public async Task ExceptionTransDemo1213() { //没写BeginTranAsync //现象:两个表数据都写进去了,没有锁表,事务没有回滚 try { await Commomn("保存第二个就抛异常", "异常---手写事务-保存第二个就抛异常"); await _rep.AsTenant().CommitTranAsync(); return 1; } catch { await _rep.AsTenant().RollbackTranAsync(); throw; } //*/ } /// /// 异常---手写事务-保存第二个就抛异常 【正确写法】【正确】 /// /// [HttpPost] [ApiDescriptionSettings(Name = "ExceptionTransDemo123")] [Description("CodeExamples/ExceptionTransDemo123")] public async Task ExceptionTransDemo123() { //var bb = "111"; //Thread.Sleep(10*1000); // 正确写法 //现象:正常报错,没有锁表,事务正常回滚 try { await _rep.AsTenant().BeginTranAsync(); await Commomn("保存第二个就抛异常", "异常---手写事务-保存第二个就抛异常"); await _rep.AsTenant().CommitTranAsync(); return 1; } catch { await _rep.AsTenant().RollbackTranAsync(); throw; } //*/ } #endregion private async Task Commomn(string flagName, string remark) { var pre = remark + "_"; //新增老师表 //新增学生表 TestTeacher testTeacher = new TestTeacher() { AliName = pre + "老师测试事务-" + YitIdHelper.NextId().ToString(), Name = pre + "老师测试事务-" + YitIdHelper.NextId().ToString(), }; TestStudent testStudent = new TestStudent() { TeacherName = testTeacher.Name, TeacherId = testTeacher.Id, AliName = pre + "学生测试事务-" + YitIdHelper.NextId().ToString(), Name = pre + "学生测试事务-" + YitIdHelper.NextId().ToString(), }; if (flagName == "未保存就抛异常") { throw Oops.Oh(flagName); } await _repTeacher.InsertAsync(testTeacher); if (flagName == "保存第一个就抛异常") { throw Oops.Oh(flagName); } await _rep.InsertAsync(testStudent); if (flagName == "保存第二个就抛异常") { throw Oops.Oh(flagName); } } /// /// 删除测试学生表 /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "Delete")] [Description("CodeExamples/Delete")] public async Task Delete(DeleteTestStudentInput input) { var entity = await _rep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002); //await _rep.FakeDeleteAsync(entity); //假删除 await _rep.DeleteAsync(entity); //真删除 } /// /// 更新测试学生表 /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "Update")] [Description("CodeExamples/Update")] public async Task Update(UpdateTestStudentInput input) { var entity = input.Adapt(); //重复性验证 await CheckExist(entity, true); await _rep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync(); } /// /// 获取测试学生表 /// /// /// [HttpGet] [ApiDescriptionSettings(Name = "Detail")] [Description("CodeExamples/Detail")] public async Task Detail([FromQuery] QueryByIdTestStudentInput input) { return await _rep.GetFirstAsync(u => u.Id == input.Id); } /// /// 获取测试学生表列表 /// /// /// [HttpGet] [ApiDescriptionSettings(Name = "List")] [Description("CodeExamples/List")] public async Task> List([FromQuery] TestStudentInput input) { return await _rep.AsQueryable().Select().ToListAsync(); } #region 私有方法 /// /// 重复性验证 /// /// 验证对象 /// 是否是编辑 /// private async Task CheckExist(TestStudent input, bool isEdit = false) { //没有配置组合校验,不需要验重 //没有配置单独校验,不需要验重 } #endregion }