mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 10:42:52 +08:00
update demo
This commit is contained in:
parent
c51cffc2c2
commit
3339d96117
@ -3,6 +3,7 @@ using FreeSql.DataAnnotations;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
@ -24,20 +25,21 @@ namespace aspnetcore_transaction.Controllers
|
||||
|
||||
[HttpGet("1")]
|
||||
//[Transactional]
|
||||
virtual public object Get([FromServices] BaseRepository<Song> repoSong, [FromServices] BaseRepository<Detail> repoDetail, [FromServices] SongRepository repoSong2,
|
||||
async public Task<object> Get([FromServices] BaseRepository<Song> repoSong, [FromServices] BaseRepository<Detail> repoDetail, [FromServices] SongRepository repoSong2,
|
||||
[FromServices] SongService serviceSong)
|
||||
{
|
||||
//repoSong.Insert(new Song());
|
||||
//repoDetail.Insert(new Detail());
|
||||
//repoSong2.Insert(new Song());
|
||||
|
||||
serviceSong.Test1();
|
||||
//serviceSong.Test1();
|
||||
await serviceSong.Test11();
|
||||
return "111";
|
||||
}
|
||||
|
||||
[HttpGet("2")]
|
||||
//[Transactional]
|
||||
async virtual public Task<object> GetAsync([FromServices] BaseRepository<Song> repoSong, [FromServices] BaseRepository<Detail> repoDetail, [FromServices] SongRepository repoSong2,
|
||||
async public Task<object> GetAsync([FromServices] BaseRepository<Song> repoSong, [FromServices] BaseRepository<Detail> repoDetail, [FromServices] SongRepository repoSong2,
|
||||
[FromServices] SongService serviceSong)
|
||||
{
|
||||
await serviceSong.Test2();
|
||||
@ -61,15 +63,21 @@ namespace aspnetcore_transaction.Controllers
|
||||
}
|
||||
|
||||
[Transactional(Propagation = Propagation.Nested)] //sqlite 不能嵌套事务,会锁库的
|
||||
public virtual void Test1()
|
||||
public void Test1()
|
||||
{
|
||||
_repoSong.Insert(new Song());
|
||||
_repoDetail.Insert(new Detail());
|
||||
_repoSong2.Insert(new Song());
|
||||
}
|
||||
[Transactional(Propagation = Propagation.Nested)] //sqlite 不能嵌套事务,会锁库的
|
||||
async public Task Test11()
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromSeconds(10)).ContinueWith(t =>
|
||||
_repoSong.InsertAsync(new Song()));
|
||||
}
|
||||
|
||||
[Transactional(Propagation = Propagation.Nested)] //sqlite 不能嵌套事务,会锁库的
|
||||
async public virtual Task Test2()
|
||||
async public Task Test2()
|
||||
{
|
||||
await _repoSong.InsertAsync(new Song());
|
||||
await _repoDetail.InsertAsync(new Detail());
|
||||
@ -77,7 +85,7 @@ namespace aspnetcore_transaction.Controllers
|
||||
}
|
||||
|
||||
[Transactional(Propagation = Propagation.Nested)] //sqlite 不能嵌套事务,会锁库的
|
||||
async public virtual Task<object> Test3()
|
||||
async public Task<object> Test3()
|
||||
{
|
||||
await _repoSong.InsertAsync(new Song());
|
||||
await _repoDetail.InsertAsync(new Detail());
|
||||
@ -110,53 +118,4 @@ namespace aspnetcore_transaction.Controllers
|
||||
public int SongId { get; set; }
|
||||
public string Title { get; set; }
|
||||
}
|
||||
|
||||
public static class IdleBusExtesions
|
||||
{
|
||||
static AsyncLocal<string> AsyncLocalTenantId = new AsyncLocal<string>();
|
||||
public static IdleBus<IFreeSql> ChangeTenant(this IdleBus<IFreeSql> ib, string tenantId)
|
||||
{
|
||||
AsyncLocalTenantId.Value = tenantId;
|
||||
return ib;
|
||||
}
|
||||
public static IFreeSql Get(this IdleBus<IFreeSql> ib) => ib.Get(AsyncLocalTenantId.Value ?? "default");
|
||||
public static IBaseRepository<T> GetRepository<T>(this IdleBus<IFreeSql> ib) where T : class => ib.Get().GetRepository<T>();
|
||||
|
||||
static void test()
|
||||
{
|
||||
IdleBus<IFreeSql> ib = null; //单例注入
|
||||
|
||||
var fsql = ib.Get(); //获取当前租户对应的 IFreeSql
|
||||
|
||||
var fsql00102 = ib.ChangeTenant("00102").Get(); //切换租户,后面的操作都是针对 00102
|
||||
|
||||
var songRepository = ib.GetRepository<Song>();
|
||||
var detailRepository = ib.GetRepository<Detail>();
|
||||
}
|
||||
|
||||
public static IServiceCollection AddRepository(this IServiceCollection services, params Assembly[] assemblies)
|
||||
{
|
||||
services.AddScoped(typeof(IBaseRepository<>), typeof(YourDefaultRepository<>));
|
||||
services.AddScoped(typeof(BaseRepository<>), typeof(YourDefaultRepository<>));
|
||||
|
||||
services.AddScoped(typeof(IBaseRepository<,>), typeof(YourDefaultRepository<,>));
|
||||
services.AddScoped(typeof(BaseRepository<,>), typeof(YourDefaultRepository<,>));
|
||||
|
||||
if (assemblies?.Any() == true)
|
||||
foreach (var asse in assemblies)
|
||||
foreach (var repo in asse.GetTypes().Where(a => a.IsAbstract == false && typeof(IBaseRepository).IsAssignableFrom(a)))
|
||||
services.AddScoped(repo);
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
|
||||
class YourDefaultRepository<T> : BaseRepository<T> where T : class
|
||||
{
|
||||
public YourDefaultRepository(IdleBus<IFreeSql> ib) : base(ib.Get(), null, null) { }
|
||||
}
|
||||
class YourDefaultRepository<T, TKey> : BaseRepository<T, TKey> where T : class
|
||||
{
|
||||
public YourDefaultRepository(IdleBus<IFreeSql> ib) : base(ib.Get(), null, null) { }
|
||||
}
|
||||
}
|
||||
|
3
Examples/aspnetcore_transaction/FodyWeavers.xml
Normal file
3
Examples/aspnetcore_transaction/FodyWeavers.xml
Normal file
@ -0,0 +1,3 @@
|
||||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
|
||||
<Rougamo />
|
||||
</Weavers>
|
26
Examples/aspnetcore_transaction/FodyWeavers.xsd
Normal file
26
Examples/aspnetcore_transaction/FodyWeavers.xsd
Normal file
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
|
||||
<xs:element name="Weavers">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="Rougamo" minOccurs="0" maxOccurs="1" type="xs:anyType" />
|
||||
</xs:all>
|
||||
<xs:attribute name="VerifyAssembly" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="GenerateXsd" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
@ -22,6 +22,7 @@ namespace aspnetcore_transaction
|
||||
{
|
||||
webBuilder.UseStartup<Startup>();
|
||||
})
|
||||
.UseServiceProviderFactory(new FreeSql.DynamicProxyServiceProviderFactory());
|
||||
//.UseServiceProviderFactory(new FreeSql.DynamicProxyServiceProviderFactory())
|
||||
;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
@ -52,6 +52,12 @@ namespace aspnetcore_transaction
|
||||
Console.OutputEncoding = Encoding.GetEncoding("GB2312");
|
||||
Console.InputEncoding = Encoding.GetEncoding("GB2312");
|
||||
|
||||
app.Use(async (context, next) =>
|
||||
{
|
||||
TransactionalAttribute.SetServiceProvider(context.RequestServices);
|
||||
await next();
|
||||
});
|
||||
|
||||
app.UseHttpMethodOverride(new HttpMethodOverrideOptions { FormFieldName = "X-Http-Method-Override" });
|
||||
app.UseDeveloperExceptionPage();
|
||||
app.UseRouting();
|
||||
|
@ -1,54 +1,43 @@
|
||||
using FreeSql;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Rougamo.Context;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FreeSql
|
||||
{
|
||||
/// <summary>
|
||||
/// 使用事务执行,请查看 Program.cs 代码开启动态代理
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class TransactionalAttribute : DynamicProxyAttribute, IActionFilter
|
||||
public class TransactionalAttribute : Rougamo.MoAttribute
|
||||
{
|
||||
public Propagation Propagation { get; set; } = Propagation.Required;
|
||||
public IsolationLevel IsolationLevel { get => _IsolationLevelPriv.Value; set => _IsolationLevelPriv = value; }
|
||||
IsolationLevel? _IsolationLevelPriv;
|
||||
public IsolationLevel IsolationLevel { get => m_IsolationLevel.Value; set => m_IsolationLevel = value; }
|
||||
IsolationLevel? m_IsolationLevel;
|
||||
|
||||
static AsyncLocal<IServiceProvider> m_ServiceProvider = new AsyncLocal<IServiceProvider>();
|
||||
public static void SetServiceProvider(IServiceProvider serviceProvider) =>
|
||||
m_ServiceProvider.Value = serviceProvider;
|
||||
|
||||
[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)
|
||||
public override void OnEntry(MethodContext context)
|
||||
{
|
||||
_uow = uowm.Begin(this.Propagation, this._IsolationLevelPriv);
|
||||
return Task.FromResult(false);
|
||||
var uowManager = m_ServiceProvider.Value.GetService(typeof(UnitOfWorkManager)) as UnitOfWorkManager;
|
||||
_uow = uowManager.Begin(this.Propagation, this.m_IsolationLevel);
|
||||
}
|
||||
Task OnAfter(Exception ex)
|
||||
public override void OnExit(MethodContext context)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ex == null) _uow.Commit();
|
||||
if (context.Exception == null) _uow.Commit();
|
||||
else _uow.Rollback();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_uow.Dispose();
|
||||
}
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
54
Examples/aspnetcore_transaction/TransactionalAttribute02.cs
Normal file
54
Examples/aspnetcore_transaction/TransactionalAttribute02.cs
Normal file
@ -0,0 +1,54 @@
|
||||
//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
|
||||
//{
|
||||
// /// <summary>
|
||||
// /// 使用事务执行,请查看 Program.cs 代码开启动态代理
|
||||
// /// </summary>
|
||||
// [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);
|
||||
// }
|
||||
// }
|
||||
//}
|
@ -11,6 +11,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Rougamo.Fody" Version="1.1.1" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="5.0.0" />
|
||||
<PackageReference Include="FreeSql.DynamicProxy" Version="1.5.0" />
|
||||
<PackageReference Include="IdleBus" Version="1.5.2" />
|
||||
|
@ -9,10 +9,5 @@
|
||||
自增
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:FreeSql.TransactionalAttribute">
|
||||
<summary>
|
||||
使用事务执行,请查看 Program.cs 代码开启动态代理
|
||||
</summary>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
||||
|
@ -800,5 +800,14 @@
|
||||
<param name="that"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:Microsoft.Extensions.DependencyInjection.FreeSqlRepositoryDependencyInjection.AddFreeRepository(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Action{FreeSql.FluentDataFilter},System.Reflection.Assembly[])">
|
||||
<summary>
|
||||
批量注入 Repository,可以参考代码自行调整
|
||||
</summary>
|
||||
<param name="services"></param>
|
||||
<param name="globalDataFilter"></param>
|
||||
<param name="assemblies"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
||||
|
Loading…
x
Reference in New Issue
Block a user