ASP.NET Core下FreeSql的倉儲事務
ASP.NET Core下FreeSql的倉儲事務
第一步:配置 Startup.cs 注入
引入包
dotnet add package FreeSql
dotnet add package FreeSql.DbContext
dotnet add package FreeSql.Provider.MySqlConnector
配置 Startup.cs 注入
public void ConfigureServices(IServiceCollection services)
{
IConfigurationSection Mysql = Configuration.GetSection("Mysql");
Fsql = new FreeSqlBuilder()
.UseConnectionString(DataType.MySql, Mysql.Value)
.UseAutoSyncStructure(true)
.UseNameConvert(NameConvertType.PascalCaseToUnderscoreWithLower)
.UseMonitorCommand(cmd => Trace.WriteLine(cmd.CommandText))
.Build();
services.AddSingleton<IFreeSql>(fsql);
services.AddScoped<UnitOfWorkManager>();
services.AddFreeRepository(null, typeof(Startup).Assembly);
//新增自己的服務,這裡只有實現
services.AddScoped<TransBlogService>();
}
- appsettings.json
{
"Mysql": "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=ovov_freesql_repository;Charset=utf8;SslMode=none;Max pool size=10",
}
UnitOfWorkManager 成員 | 說明 |
---|---|
IUnitOfWork Current | 返回當前的工作單元 |
void Binding(repository) | 將倉儲的事務交給它管理 |
IUnitOfWork Begin(propagation, isolationLevel) | 創建工作單元 |
- TransBlogService.cs
private readonly IBaseRepository<Blog, int> _blogRepository;
private readonly IBaseRepository<Tag, int> _tagRepository;
private readonly UnitOfWorkManager _unitOfWorkManager;
public TransBlogService(IBaseRepository<Blog, int> blogRepository, IBaseRepository<Tag, int> tagRepository,UnitOfWorkManager unitOfWorkManager)
{
_blogRepository = blogRepository ;
_tagRepository = tagRepository ;
_unitOfWorkManager = unitOfWorkManager;
}
public async Task CreateBlogUnitOfWorkAsync(Blog blog,List<Tag>tagList)
{
using (IUnitOfWork unitOfWork = _unitOfWorkManager.Begin())
{
try
{
await _blogRepository.InsertAsync(blog);
tagList.ForEach(r =>
{
r.PostId = blog.Id;
});
await _tagRepository.InsertAsync(tagList);
unitOfWork.Commit();
}
catch (Exception e)
{
//實際 可以不Rollback。因為IUnitOfWork內部Dispose,會把沒有Commit的事務Rollback回來,但能提前Rollback
unitOfWork.Rollback();
//記錄日誌、或繼續throw;出來
}
}
}
public async Task UpdateBlogAsync(int id)
{
using (IUnitOfWork unitOfWork = _unitOfWorkManager.Begin())
{
try
{
Blog blog = _blogRepository.Select.Where(r => r.Id == id).First();
blog.IsDeleted = true;
await _blogRepository.UpdateAsync(blog);
unitOfWork.Commit();
}
catch (Exception e)
{
//記錄日誌、或繼續throw;出來
unitOfWork.Rollback();
}
}
}
IUnitOfWork 成員 | 說明 |
---|---|
IFreeSql Orm | 該對象 Select/Delete/Insert/Update/InsertOrUpdate 與工作單元事務保持一致,可省略傳遞 WithTransaction |
DbTransaction GetOrBeginTransaction() | 開啟事務,或者返回已開啟的事務 |
void Commit() | 提交事務 |
void Rollback() | 回滾事務 |
DbContext.EntityChangeReport EntityChangeReport | 工作單元內的實體變化跟蹤 |
完整的程式碼
以上使用的是泛型倉儲,那我們如果是重寫一個倉儲 如何保持和UnitOfWorkManager
同一個事務呢。
繼承現有的DefaultRepository<,>
倉儲,實現自定義的倉儲BlogRepository.cs
,
public class BlogRepository : DefaultRepository<Blog, int>, IBlogRepository
{
public BlogRepository(UnitOfWorkManager uowm) : base(uowm?.Orm, uowm)
{
}
public List<Blog> GetBlogs()
{
return Select.Page(1, 10).ToList();
}
}
其中介面。IBlogRepository.cs
public interface IBlogRepository : IBaseRepository<Blog, int>
{
List<Blog> GetBlogs();
}
在 startup.cs注入此服務
services.AddScoped<IBlogRepository, BlogRepository>();