📚
Hoa Framework
  • 一、框架指南
  • 二、功能特性
  • 三、源码结构
  • 四、代码规范
  • 五、入门指南
  • 六、依赖注入/控制反转
  • 七、控制器和服务
  • 八、对象映射指南
  • 九、数据库操作指南
    • 9.1、正向工程(Code First)
    • 9.2、逆向工程(Database First)
    • 9.3、关于仓储(IRepository)
    • 9.4、增删改操作
    • 9.5、查询操作
    • 9.6、DataSet、DataTable 操作
    • 9.7、查询结果集映射
    • 9.8、批量增删改操作
    • 9.9、存储过程、视图、函数操作
    • 9.10、工作单元和事务
    • 9.11、多上下文、读写分离
    • 9.12、切面上下文(TangentDbContext)
    • 9.13、其他操作
    • 9.14、EF Core 高性能
    • 9.15、常见错误
  • 十、开放接口指南
    • 10.1、RESTFul 和 Swagger
    • 10.2、规范化返回值
  • 十一、数据校验
  • 十二、安全授权
  • 十三、异常处理
  • 十四、日志管理
  • 十五、配置管理
  • 十六、缓存管理
  • 十七、内置工具类
    • 17.1、数据加解密
  • 十八、跨域处理
  • 十九、筛选拦截器(未)
  • 二十、进程服务(Daemon)
  • 二十一、编写测试
    • 20.1、单元测试
    • 20.2、基准测试
    • 20.3、性能测试
  • 二十二、托管部署
    • 22.1、IIS 托管部署
    • 22.2、Nginx 托管部署
    • 22.3、Docker 容器部署
  • 二十三、性能分析(MiniProfiler)
  • 二十四、其他功能
    • 23.1、第三方包管理
    • 23.2、文件上传下载
    • 23.3、Razor 视图引擎
    • 23.4、生成客户端请求代码
    • 23.5、快捷操作
  • 二十五、Docker 容器化
    • 25.1、Docker 介绍
    • 25.2、Docker 安装
    • 25.3、Docker 安装服务
    • 25.4、Docker 常用命令
    • 25.6、Docker run 常用命令
    • 25.7、Docker-Compose 介绍
    • 25.8、docker-compose.yml
    • 25.9、Docker-Compose 常用命令
    • 25.10、Docker-Compose 转换 docker run
    • 25.11、Docker 构建自己的镜像
    • 25.12、Dockerfile指南
    • 25.13、Dockerfile 常用命令
    • 25.14、Dockerfile 打包、上传、分享
    • 25.15、Docker 数据卷
    • 25.16、Docker 域网络
    • 25.17、Docker + Nginx 实现分布式集群、负载均衡
  • 二十六、DevOps 持续部署集成
    • 26.1、DevOps 介绍
    • 26.2、持续集成、交付、部署
    • 26.3、Jenkins 介绍
    • 26.4、Jenkins 安装
    • 26.5、Jenkins 初始化
    • 26.6、Jenkins 实战演练
    • 26.7、Jenkis 项目配置
    • 26.8、Jenkins 插件
  • 二十七、OpenXml/Excel 操作
  • 二十八、SaaS 多租户
  • 二十九、Git 代码管理
    • 29.1、Git 介绍
    • 29.2、Git 安装
    • 29.3、Git 基础配置
    • 29.4、Git 工作流程
    • 29.5、Git 重要概念
    • 29.6、Git 创建仓库
    • 29.7、Git 基本操作
    • 29.8、Git 分支管理
    • 29.9、Git 查看提交历史
    • 29.10、Git 标签
    • 29.11、Git 拉取/获取/推送
    • 28.12、Git GUI工具
    • 29.13、Git 私有化部署
    • 29.14、Git 推荐开发模式
    • 29.15、Svn 转 Git
  • 贡献代码
  • 更新日志
由 GitBook 提供支持
在本页
  • 什么是切面上下文
  • 传统写法(以后不推荐)
  • 如何使用(推荐)
  • 第一步
  • 第二步
  • 特性说明
  • 支持返回值
  • 支持元组返回多个值
  • 支持复杂类型返回并自动映射
  • 多上下文配置
  • 自动映射到Dto类型
  • 特别注意

这有帮助吗?

  1. 九、数据库操作指南

9.12、切面上下文(TangentDbContext)

切面上下文是一种全新的面向切面操作数据库方式。

什么是切面上下文

切面上下文是 Hoa Framework 框架独创的面向切面方式操作数据库方式,主要用来解决 sql 语句、存储过程、函数调用情况。

可能有些时候我们避免不了写 sql 的方式(特别注意,除非 Linq/Lambda 方式不能做到,才用切面上下文),如:

传统写法(以后不推荐)

// sql方式
_testRepository.FromSql("select name from test where id=@id"
        , new SqlParameter[]{ new SqlParameter("@id", 1) });
        
// 执行存储过程
_testRepository.SqlProcedureQuery("PROC_Name", new ProcModel(){});

// 执行函数
_testRepository.SqlFunctionQuery("Func_Name", new FuncModel(){});

上面的方式似乎没有上面问题,但是如果多个地方需要用到这些 sql 或 存储过程 或 函数调用,就会散落到处都是,不利于维护。

所以,Hoa Framework 框架设计出全新的方式,主要用来解决上述代码多次调用散落问题。

如何使用(推荐)

第一步

定义一个接口(只需要接口),并继承 ITangentDependency接口,如:IFallScatteredQuery,如:

using Hoa.DbManager.Tangents;

namespace Hoa.Application
{
    // 必须继承 ITangentDependency 接口
    public interface IFallScatteredQuery: ITangentDependency
    {
        // 执行原始 sql 查询
        [Sentence("select name from dbo.test where id=@id")]
        string GetName(int id);
        
        // 执行存储过程
        [Procedure("PROC_Name")]
        IEnumerable<Test> GetProcResult(object model);
        
        // 执行函数
        [ScalarFunction("Func_Name")]
        int GetFuncReuslt(object model);
    }
}

第二步

通过依赖注入 ITangentDbContext 切面上下文接口,并调用 For<T> 进行初始化,如:

using Hoa.Application;
using Hoa.DbManager.Tangents;
using Microsoft.AspNetCore.Mvc;

namespace Hoa.Web.Host.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class HoaController : ControllerBase
    {
        // 构造函数初始化
        private readonly IFallScatteredQuery _tangent;
        public HoaController(ITangentDbContext tangentDbContext)
        {
            // 解析接口信息
            _tangent = tangentDbContext.For<IFallScatteredQuery>();
        }

        [HttpGet]
        [Route(nameof(Test))]
        public string Test()
        {
           // 执行sql
           var name = _tangent.GetName(1);    // 自动查询数据库
           
           // 执行存储过程
           var tests = _tangent.GetProcResult(new { name = "Monk" });
           
           // 执行函数
           var num = _tangent.GetFuncReuslt(new { id = 10});
           
           return "Powered by Monk";
        }
    }
}

神奇吧!通过这种方式,Hoa Framework 会自动查询数据库并转换成指定的结果。再也不怕代码难维护了!😘

特性说明

目前 切面上下文支持 三种 特性解析:

  • [Sentence(sql, DbContextIdentifier=)]:支持传入 sql 语句,支持命令参数防止 sql 注入。

  • [Procedure(name, DbContextIdentifier=)]:支持传入存储过程名称

  • [ScalarFunction(name, DbContextIdentifier=)]:支持传入函数名称

支持返回值

TangentDbContext 几乎支持所有返回值类型,如:

  • Object

  • 除了 Enum 以外的所有值类型和 string 类型,如:int, bool, decimal, string, float, long等等

  • 所有可枚举集合类型,包括 Array,List,IEnumerable等

  • DataTable 和 DataSet 类型

  • ValueTuple 元组类型

支持元组返回多个值

using Hoa.DbManager.Tangents;
using System.Collections.Generic;
using System.Data;

namespace Hoa.Application
{
    public interface IFallScatteredQuery : ITangentDependency
    {
        [Sentence(@"
            select * from dbo.brokers;
            select * from dbo.brokers where id > @id;
            select * from dbo.brokers where name = @name
        ")]
        DataSet GetDataSet(int id, string name);

        [Sentence(@"
            select top 2 * from dbo.brokers;
            select * from dbo.brokers where id > @id;
            select * from dbo.brokers where name = @name
        ")]
        (IEnumerable<Broker> brokers1, IEnumerable<Broker> brokers2, IEnumerable<Broker> brokers3) GetValueTuple(int id, string name);
    }
}
var dataset = _tangent.GetDataSet(1, "Monk2");
var (broker1, borker2, borker3) = _tangent.GetValueTuple(0, "Monk");

支持复杂类型返回并自动映射

[Procedure("PROC_Name", SourceType = typeof((A, IEnumerable<B>, IEnumerable<C>, IEnumerable<D>)))]
(ADto a, IEnumerable<BDto> b, IEnumerable<CDto> c, IEnumerable<DDto> d) PRGetPersonDemographicDetail(Parameter_PersonID parameter);
config.ForType<A, ADto>().ConvertSourceMemberUnderlineSplitNameToCamelCase();
config.ForType<(A a, IEnumerable<B> b, IEnumerable<C> a, IEnumerable<D> d), (ADto aDto, IEnumerable<BDto> bDto, IEnumerable<CDto> cDto, IEnumerable<DDto> dDto)>()
                .ConvertSourceMemberUnderlineSplitNameToCamelCase()
                .Map(dest => dest.aDto, src => src.a)
                .Map(dest => dest.aDto.B, src => src.b)
                .Map(dest => dest.aDto.C, src => src.c)
                .Map(dest => dest.aDto.D, src => src.d);

多上下文配置

切面上下文还支持多上下文操作,如:

using Hoa.Core;
using Hoa.Core.Web.Entities;
using Hoa.DbManager.Tangents;
using System.Collections.Generic;

namespace Hoa.Application
{
    public interface IFallScatteredQuery : ITangentDependency
    {
        [Procedure("PROC_Name", DbContextIdentifier = typeof(OtherDbContextIdentifier))]
        IEnumerable<Entity> GetEntities(Model parameter);
    }
}

自动映射到Dto类型

通常我们数据库返回的是我们的实体模型,这个时候,我们还需要手动的调用 .Adapt<DtoType> 到 DtoType 类型,所以,切面上下文提供了一种更加便捷的方式,只需要指定 SouceType 即可,如:

using Hoa.Core;
using Hoa.Core.Web.Entities;
using Hoa.DbManager.Tangents;
using System.Collections.Generic;

namespace Hoa.Application
{
    public interface IFallScatteredQuery : ITangentDependency
    {
        // 设置SourceType 为执行真正的返回值,然后方法的返回值设置为Dto即可
        // 实际上内部会自动帮你将 SourceType 类型  Adapt 到 方法的返回值类型
        
        [Procedure("PROC_Name", SouceType = typeof(IEnumerable<Entity>))]
        IEnumerable<Dto> GetDtos(Model parameter);
    }
}

特别注意

不建议在切面上下文中做 增删改操作(即使框架本身支持)!!!!

上一页9.11、多上下文、读写分离下一页9.13、其他操作

最后更新于4年前

这有帮助吗?

其中 DbContextIdentifier 参数是 Type 类型,也就是 数据库上下文标识类。见 章节

9.11、多上下文、读写分离