一、引言

  接着上一篇的教程,本章我们继续讲SmartSql。今天的主题是动态仓储。

  老规矩,先上一个项目结构

  从第二章开始。我们将原来的单一项目做了一个分离。方便之后的更新。

  在这个结构中。原本上一章的DataAccess没有了。取而代之的是Repository。这个就是动态仓储的项目。接下来我们从这个Repository项目开始说。这也是动态仓储的核心。

二、Repository项目

1. Nuget依赖

  SmartSql有一个独立的动态仓储库,即:SmartSql.DyRepository。如果你想使用动态仓储,引用它就行啦。

2. 第一个仓储接口

  引用完库,接下来就是创建我们的第一个仓储接口—IArticleRepository。废话不到,先上代码再一一解释。

 using SmartSql.DyRepository;
using SmartSql.DyRepository.Annotations;
using SmartSqlSampleChapterTwo.Entity;
using System.Data; namespace SmartSqlSampleChapterTwo.Repository
{
[SqlMap(Scope = "CustomScope")]
public interface IArticleRepository : IRepository<T_Article, long>
{
[Statement(CommandType = CommandType.Text, Execute = ExecuteBehavior.ExecuteScalar, Id = "Offline")]
int OfflineArticle([Param("Id", FieldType = typeof(long))] long articleId); [Statement(Sql = "Update T_Article Set Status = 1 Where Id = @Id")]
int OnlineArticle([Param("Id")] long article);
}
}

IArticleRepository

2.1 默认接口 IRepository

  看完代码是不是发现和上一章的DataAccess有很大的区别,那些CURD的方法都没有了。

  这是SmartSql内置的一些默认接口,它包括以下这些接口,这些接口基本可以满足大部分普通业务场景了。

 int Insert(TEntity entity);

 int Update(TEntity entity);

 [Statement(Id = "Update")]
int DyUpdate(object dyObj); int Delete(object reqParams); [Statement(Id = "Delete")]
int DeleteById([Param("Id")] TPrimary id); TEntity GetEntity(object reqParams); [Statement(Id = "GetEntity")]
TEntity GetById([Param("Id")] TPrimary id); [Statement(Execute = ExecuteBehavior.ExecuteScalar)]
int GetRecord(object reqParams); IList<TEntity> QueryByPage(object reqParams); IList<TEntity> Query(object reqParams); [Statement(Execute = ExecuteBehavior.ExecuteScalar)]
bool IsExist(object reqParams);

2.2 SqlMap特性

  这个特性是用于指定Scope的配置。这个对应于Map中的Scope属性。这里我定义了“CustomScope”。那对应的Map中也将与之对应。如下图:

  

2.3 Statement特性

  这个特性略微有点复杂,其中包含了6个属性,接下来我们一个个看。

2.3.1 Scope

  这个特性和SqlMap的Scope作用是一样的。区别在于Statement的级别更高。

2.3.2 Id

  指定此函数所使用的Statement。依据是Id。例:

// 接口定义
[Statement(Id = "TestId")]
int CustomStatementId();
<!-- Statement定义 -->
<Statement Id="TestId">
db script...
</Statement>

2.3.3 Execute

  Execute是一个ExecuteBehavior枚举,用于指定此函数执行Sql脚本的方式。

ExecuteBehavior
Auto ORM自动识别
Execute 返回影响行数,主要用于执行写操作。
ExecuteScalar 返回第一行第一列的数据,主要用于返回自增主键和获取结果数
Query 返回List
QuerySingle 返回第一行数据
GetDataTable 返回DataTable
GetDataSet 返回DataSet

  

2.3.4 Sql

  特殊场景下,可以直接使用此属性定义Sql脚本,而不用配置SqlMap。如IArticleRepository的OnlineArticle定义。

2.3.5 CommandType

  这个属性是ADO.NET的CommandType枚举。作用也完全相同

2.3.6 SourceChoice

  指定数据源,可以指定Write或Read。

3. Startup

  在上一章节中,我们在Startup中注册了SmartSql,现在我们要继续注册动态仓储。代码也很简单,只要在AddSmart方法完成后继续调用AddRepositoryFromAssembly即可。如下:

services.AddSmartSql(builder =>
{
builder.UseAlias("SmartSqlSampleChapterTwo"); // 定义实例别名,在多库场景下适用。
//.UseXmlConfig(ResourceType.File,"MyConfig.xml");
}).AddRepositoryFromAssembly(options =>
{
// SmartSql实例的别名
options.SmartSqlAlias = "SmartSqlSampleChapterTwo";
// 仓储接口所在的程序集全称
options.AssemblyString = "SmartSqlSampleChapterTwo.Repository";
// 筛选器,根据接口的Type筛选需要的仓储
options.Filter = type => type.FullName.Contains("Sample");
// Scope模板,默认是"I{Scope}Repository"
options.ScopeTemplate = "I{Scope}Repository";
});

  这个方法中会抛出一个AssemblyAutoRegisterOptions,方便用户注册指定的仓储。

4. Controller的变化

  在Sample中,我们直接让Controller引用了Repository,实际场景中。我们可以在任何需要仓储的地方引用仓储。代码如下:

using Microsoft.AspNetCore.Mvc;
using SmartSqlSampleChapterTwo.Entity;
using SmartSqlSampleChapterTwo.Repository;
using System.Collections.Generic; namespace SmartSqlSampleChapterTwo.Api.Controllers
{
/// <summary>
///
/// </summary>
[Route("[controller]/[action]")]
public class ArticleController : Controller
{
private readonly IArticleRepository _articleRepository; /// <summary>
/// constructor
/// </summary>
/// <param name="articleRepository"></param>
public ArticleController(IArticleRepository articleRepository)
{
_articleRepository = articleRepository;
} /// <summary>
///
/// </summary>
/// <param name="article"></param>
/// <returns></returns>
[HttpPost]
public T_Article Add([FromBody] T_Article article)
{
article.Id = _articleRepository.Insert(article);
return article;
} /// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet]
public T_Article Get([FromQuery] long id)
{
return _articleRepository.GetById(id);
} /// <summary>
///
/// </summary>
/// <param name="article"></param>
/// <returns></returns>
[HttpPost]
public bool Update([FromBody] T_Article article)
{
return _articleRepository.Update(article) > ;
} /// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <param name="status"></param>
/// <returns></returns>
[HttpPost]
public bool UpdateStatus([FromQuery] long id, [FromQuery] int status)
{
return _articleRepository.DyUpdate(new
{
Id = id,
Status = status
}) > ;
} /// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet]
public bool IsExist([FromQuery] long id)
{
return _articleRepository.IsExist(new
{
Id = id
});
} /// <summary>
///
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
[HttpGet]
public IEnumerable<T_Article> Query([FromQuery] string key = "")
{
return _articleRepository.Query(new
{
Title = key
});
} /// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet]
public int Offline([FromQuery] long id)
{
return _articleRepository.OfflineArticle(id);
} /// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet]
public int Online([FromQuery] long id)
{
return _articleRepository.OnlineArticle(id);
}
}
}

ArticleController

  可以注意到的是,除了把DataAccess变成了Repository。其他的代码几乎没有改动。最后我还添加了仓储自定义的接口的调用。

5. 结语

  今天,我们了解了动态仓储的使用。它是一个非常方便的特性,可以非常显著的提升我们写代码的效率,减少一定的代码量,避免了很多“体力活”。让我们专注于业务!

示例代码链接在这里

下期预告:SmartSql中的事务,及AOP的使用

最新文章

  1. (转)TortoiseSVN与VisualSVN Server搭建SVN版本控制系统
  2. POJ 1274 The Perfect Stall、HDU 2063 过山车(最大流做二分匹配)
  3. CentOS 7 64位的安装流程
  4. Android网络请求框架
  5. HBM内存介绍
  6. 在ASP.NET非MVC环境中(WebForm中)构造MVC的URL参数
  7. touch 命令
  8. IOS中字符串操作
  9. 通过文件流stream下载文件
  10. 配置phpmyadmin使登录时可填写IP管理多台MySQL 连接多个数据库 自动登录
  11. 框架中web.xml中配置文件解析
  12. php中怎么实现后台执行?
  13. SQL Server 一些重要视图4
  14. Android ListView getViewTypeCount 的返回值问题解决
  15. 基于 Consul 实现 MagicOnion(GRpc) 服务注册与发现
  16. Java并发编程(十)-- Java中的锁
  17. Django-website 程序案例系列-14 缓存的应用配置文件的写法
  18. 【linux】16进制格式查看命令hexdump
  19. hdu-4080 Stammering Aliens 字符串hash 模板题
  20. NavicatForOracle无法连接数据库,报错ORA-28547

热门文章

  1. 全能,OnSize的使用,部分覆盖后重画,都没有问题
  2. 快速学习Symfony4,Symfony4教程
  3. SPOJ - SUBST1 New Distinct Substrings —— 后缀数组 单个字符串的子串个数
  4. POJ1625 Censored! —— AC自动机 + DP + 大数
  5. 使用libcurl,根据url下载对应html页面
  6. riverbed 流量分析——还是在基于流量做运维
  7. C#SocketAsyncEventArgs实现高效能多并发TCPSocket通信 (服务器实现)
  8. 如何在u盘上安装系统, (非安装盘)
  9. 浅析linux 下shell命令执行和守护进程
  10. 机器学习:Selective Search for Object Recognition