diff --git a/Examples/aspnetcore_transaction/Domain/SongRepository.cs b/Examples/aspnetcore_transaction/Domain/SongRepository.cs new file mode 100644 index 00000000..352dd6b7 --- /dev/null +++ b/Examples/aspnetcore_transaction/Domain/SongRepository.cs @@ -0,0 +1,35 @@ +using System; +using System.ComponentModel; +using System.Threading.Tasks; +using FreeSql; +using FreeSql.DataAnnotations; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; + +namespace aspnetcore_transaction.Domain +{ + public class SongRepository : DefaultRepository + { + public SongRepository(UnitOfWorkManager uowm) : base(uowm?.Orm, uowm) { } + } + + [Description("123")] + public class Song + { + /// + /// 自增 + /// + [Column(IsIdentity = true)] + [Description("自增id")] + public int Id { get; set; } + public string Title { get; set; } + } + public class Detail + { + [Column(IsIdentity = true)] + public int Id { get; set; } + + public int SongId { get; set; } + public string Title { get; set; } + } +} diff --git a/Examples/aspnetcore_transaction/Program.cs b/Examples/aspnetcore_transaction/Program.cs index 7d61ff83..282417ed 100644 --- a/Examples/aspnetcore_transaction/Program.cs +++ b/Examples/aspnetcore_transaction/Program.cs @@ -16,7 +16,6 @@ namespace aspnetcore_transaction { webBuilder.UseStartup(); }) - //.UseServiceProviderFactory(new FreeSql.DynamicProxyServiceProviderFactory()) ; } } diff --git a/Examples/aspnetcore_transaction/Properties/launchSettings.json b/Examples/aspnetcore_transaction/Properties/launchSettings.json deleted file mode 100644 index df5dd806..00000000 --- a/Examples/aspnetcore_transaction/Properties/launchSettings.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:64513/", - "sslPort": 44328 - } - }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "dbcontext_01": { - "commandName": "Project", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "applicationUrl": "http://localhost:35351/" - } - } -} \ No newline at end of file diff --git a/Examples/aspnetcore_transaction/Services/SongService.cs b/Examples/aspnetcore_transaction/Services/SongService.cs new file mode 100644 index 00000000..6e1d4275 --- /dev/null +++ b/Examples/aspnetcore_transaction/Services/SongService.cs @@ -0,0 +1,57 @@ +using System; +using System.ComponentModel; +using System.Threading.Tasks; +using aspnetcore_transaction.Domain; +using FreeSql; +using FreeSql.DataAnnotations; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; + +namespace aspnetcore_transaction.Services +{ + public class SongService + { + BaseRepository _repoSong; + BaseRepository _repoDetail; + SongRepository _repoSong2; + + public SongService(BaseRepository repoSong, BaseRepository repoDetail, SongRepository repoSong2) + { + var tb = repoSong.Orm.CodeFirst.GetTableByEntity(typeof(Song)); + _repoSong = repoSong; + _repoDetail = repoDetail; + _repoSong2 = repoSong2; + } + + [Transactional(Propagation = Propagation.Nested)] //sqlite 不能嵌套事务,会锁库的 + public void Test1() + { + _repoSong.Insert(new Song()); + _repoDetail.Insert(new Detail()); + _repoSong2.Insert(new Song()); + } + [Transactional(Propagation = Propagation.Nested)] //sqlite 不能嵌套事务,会锁库的 + public Task Test11() + { + return Task.Delay(TimeSpan.FromSeconds(1)).ContinueWith(t => + _repoSong.InsertAsync(new Song())); + } + + [Transactional(Propagation = Propagation.Nested)] //sqlite 不能嵌套事务,会锁库的 + public async Task Test2() + { + await _repoSong.InsertAsync(new Song()); + await _repoDetail.InsertAsync(new Detail()); + await _repoSong2.InsertAsync(new Song()); + } + + [Transactional(Propagation = Propagation.Nested)] //sqlite 不能嵌套事务,会锁库的 + public async Task Test3() + { + await _repoSong.InsertAsync(new Song()); + await _repoDetail.InsertAsync(new Detail()); + await _repoSong2.InsertAsync(new Song()); + return "123"; + } + } +} diff --git a/Examples/aspnetcore_transaction/Startup.cs b/Examples/aspnetcore_transaction/Startup.cs index bbaffcd1..9744693e 100644 --- a/Examples/aspnetcore_transaction/Startup.cs +++ b/Examples/aspnetcore_transaction/Startup.cs @@ -1,5 +1,6 @@ using System; using System.Diagnostics; +using System.Linq; using System.Text; using aspnetcore_transaction.Controllers; using FreeSql; @@ -35,7 +36,11 @@ namespace aspnetcore_transaction services.AddSingleton(Fsql); services.AddScoped(); - services.AddFreeRepository(null, typeof(Startup).Assembly); + + //批量注入 + foreach (var repo in typeof(Startup).Assembly.GetTypes() + .Where(a => a.IsAbstract == false && typeof(IBaseRepository).IsAssignableFrom(a))) + services.AddScoped(repo); services.AddScoped(); } diff --git a/Examples/aspnetcore_transaction/TransactionalAttribute02.cs b/Examples/aspnetcore_transaction/TransactionalAttribute02.cs deleted file mode 100644 index fb4629ee..00000000 --- a/Examples/aspnetcore_transaction/TransactionalAttribute02.cs +++ /dev/null @@ -1,54 +0,0 @@ -//using FreeSql; -//using Microsoft.AspNetCore.Mvc.Filters; -//using System; -//using System.Collections.Generic; -//using System.Data; -//using System.Text; -//using System.Threading.Tasks; - -//namespace FreeSql -//{ -// /// -// /// 使用事务执行,请查看 Program.cs 代码开启动态代理 -// /// -// [AttributeUsage(AttributeTargets.Method)] -// public class TransactionalAttribute : DynamicProxyAttribute, IActionFilter -// { -// public Propagation Propagation { get; set; } = Propagation.Required; -// public IsolationLevel IsolationLevel { get => _IsolationLevelPriv.Value; set => _IsolationLevelPriv = value; } -// IsolationLevel? _IsolationLevelPriv; - -// [DynamicProxyFromServices] -//#pragma warning disable IDE0044 // 添加只读修饰符 -// UnitOfWorkManager _uowManager; -//#pragma warning restore IDE0044 // 添加只读修饰符 -// IUnitOfWork _uow; - -// public override Task Before(DynamicProxyBeforeArguments args) => OnBefore(_uowManager); -// public override Task After(DynamicProxyAfterArguments args) => OnAfter(args.Exception); - -// //这里是为了 controller -// public void OnActionExecuting(ActionExecutingContext context) => OnBefore(context.HttpContext.RequestServices.GetService(typeof(UnitOfWorkManager)) as UnitOfWorkManager); -// public void OnActionExecuted(ActionExecutedContext context) => OnAfter(context.Exception); - - -// Task OnBefore(UnitOfWorkManager uowm) -// { -// _uow = uowm.Begin(this.Propagation, this._IsolationLevelPriv); -// return Task.FromResult(false); -// } -// Task OnAfter(Exception ex) -// { -// try -// { -// if (ex == null) _uow.Commit(); -// else _uow.Rollback(); -// } -// finally -// { -// _uow.Dispose(); -// } -// return Task.FromResult(false); -// } -// } -//} diff --git a/Examples/aspnetcore_transaction/aspnetcore_transaction.csproj b/Examples/aspnetcore_transaction/aspnetcore_transaction.csproj index 32a8331c..af2fe669 100644 --- a/Examples/aspnetcore_transaction/aspnetcore_transaction.csproj +++ b/Examples/aspnetcore_transaction/aspnetcore_transaction.csproj @@ -11,15 +11,10 @@ + + - - - - - - - diff --git a/Examples/aspnetcore_transaction/aspnetcore_transaction.xml b/Examples/aspnetcore_transaction/aspnetcore_transaction.xml index d301a332..9ec825a1 100644 --- a/Examples/aspnetcore_transaction/aspnetcore_transaction.xml +++ b/Examples/aspnetcore_transaction/aspnetcore_transaction.xml @@ -9,5 +9,10 @@ 自增 + + + 自增 + + diff --git a/Examples/aspnetcore_transaction/aspnetcore经典示范.zip b/Examples/aspnetcore_transaction/aspnetcore经典示范.zip new file mode 100644 index 00000000..d7f302ae Binary files /dev/null and b/Examples/aspnetcore_transaction/aspnetcore经典示范.zip differ diff --git a/FreeSql-lite.sln b/FreeSql-lite.sln index eefc4343..a5b72d42 100644 --- a/FreeSql-lite.sln +++ b/FreeSql-lite.sln @@ -79,6 +79,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "base_entity", "Examples\bas EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FreeSql.Provider.OracleOledb", "Providers\FreeSql.Provider.OracleOledb\FreeSql.Provider.OracleOledb.csproj", "{19D2E22A-B000-46B6-AFC8-60BF01A51C9A}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "aspnetcore_transaction", "Examples\aspnetcore_transaction\aspnetcore_transaction.csproj", "{28163C3B-B2E6-432D-AAC3-F5F19374BE31}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -425,6 +427,18 @@ Global {19D2E22A-B000-46B6-AFC8-60BF01A51C9A}.Release|x64.Build.0 = Release|Any CPU {19D2E22A-B000-46B6-AFC8-60BF01A51C9A}.Release|x86.ActiveCfg = Release|Any CPU {19D2E22A-B000-46B6-AFC8-60BF01A51C9A}.Release|x86.Build.0 = Release|Any CPU + {28163C3B-B2E6-432D-AAC3-F5F19374BE31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {28163C3B-B2E6-432D-AAC3-F5F19374BE31}.Debug|Any CPU.Build.0 = Debug|Any CPU + {28163C3B-B2E6-432D-AAC3-F5F19374BE31}.Debug|x64.ActiveCfg = Debug|Any CPU + {28163C3B-B2E6-432D-AAC3-F5F19374BE31}.Debug|x64.Build.0 = Debug|Any CPU + {28163C3B-B2E6-432D-AAC3-F5F19374BE31}.Debug|x86.ActiveCfg = Debug|Any CPU + {28163C3B-B2E6-432D-AAC3-F5F19374BE31}.Debug|x86.Build.0 = Debug|Any CPU + {28163C3B-B2E6-432D-AAC3-F5F19374BE31}.Release|Any CPU.ActiveCfg = Release|Any CPU + {28163C3B-B2E6-432D-AAC3-F5F19374BE31}.Release|Any CPU.Build.0 = Release|Any CPU + {28163C3B-B2E6-432D-AAC3-F5F19374BE31}.Release|x64.ActiveCfg = Release|Any CPU + {28163C3B-B2E6-432D-AAC3-F5F19374BE31}.Release|x64.Build.0 = Release|Any CPU + {28163C3B-B2E6-432D-AAC3-F5F19374BE31}.Release|x86.ActiveCfg = Release|Any CPU + {28163C3B-B2E6-432D-AAC3-F5F19374BE31}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -454,10 +468,11 @@ Global {D4FEE5C1-6805-4B46-B10B-BE5CC942B883} = {2A381C57-2697-427B-9F10-55DA11FD02E4} {9D82A683-2950-4E8A-B078-A422ECA6AAA5} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} {19D2E22A-B000-46B6-AFC8-60BF01A51C9A} = {2A381C57-2697-427B-9F10-55DA11FD02E4} + {28163C3B-B2E6-432D-AAC3-F5F19374BE31} = {94C8A78D-AA15-47B2-A348-530CD86BFC1B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - RESX_NeutralResourcesLanguage = en-US - RESX_PrefixTranslations = True SolutionGuid = {089687FA-5D21-40AC-BA8A-AA0D1E1H7F98} + RESX_PrefixTranslations = True + RESX_NeutralResourcesLanguage = en-US EndGlobalSection EndGlobal