ASP.NET Core:使用Dapper和SwaggerUI來豐富你的系統框架
一、概述
1、用VS2017創建如下圖的幾個.NET Standard類庫,默認版本為1.4,你可以通過項目屬性進行修改,最高支持到1.6,大概五月份左右會更新至2.0,API會翻倍,很期待!
排名分先後,這裏簡要說下我對各個類庫職責的一個理解。
|
2、當然了,你還可以通過.NET Core Tool的cli命令來創建,前提是你的電腦上安裝了.NET Core SDK。
dotnet new classlib -n Light.Repository //創建一個名字為Light.Repository的.NET Standard類庫
更多創建類型請鍵入如下命令進行查看
dotnet new -all
紅框內自上而下依次表示:
- 控制臺應用程序
- 類庫
- 微軟自帶的單元測試項目
- 引入XUnit框架的單元測試項目
- 空的ASP.NET Core
- ASP.NET Core MVC項目
- ASP.NET Core WebAPI項目
- 空的解決方案
二、引入Dapper
1、準備創建用戶表的SQL腳本
1 USE [Light] 2 GO 3 4 /****** Object: Table [dbo].[User] Script Date: 2017/3/27 22:40:08 ******/ 5 SET ANSI_NULLS ON 6 GO 7 8 SET QUOTED_IDENTIFIER ON 9 GO 10 11 CREATE TABLE [dbo].[User]( 12 [Id] [int] IDENTITY(10000,1) NOT NULL, 13 [UserName] [nvarchar](50) NOT NULL, 14 [Password] [nvarchar](50) NOT NULL, 15 [Gender] [bit] NOT NULL, 16 [Birthday] [datetime] NOT NULL, 17 [CreateUserId] [int] NOT NULL, 18 [CreateDate] [datetime] NOT NULL, 19 [UpdateUserId] [int] NOT NULL, 20 [UpdateDate] [datetime] NOT NULL, 21 [IsDeleted] [bit] NOT NULL, 22 CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED 23 ( 24 [Id] ASC 25 )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 26 ) ON [PRIMARY] 27 28 GO 29 30 ALTER TABLE [dbo].[User] ADD CONSTRAINT [DF_User_UserName] DEFAULT (‘‘) FOR [UserName] 31 GO 32 33 ALTER TABLE [dbo].[User] ADD CONSTRAINT [DF_User_Password] DEFAULT (‘‘) FOR [Password] 34 GO 35 36 ALTER TABLE [dbo].[User] ADD CONSTRAINT [DF_User_Gender] DEFAULT ((0)) FOR [Gender] 37 GO 38 39 ALTER TABLE [dbo].[User] ADD CONSTRAINT [DF_User_Birthday] DEFAULT (getdate()) FOR [Birthday] 40 GO 41 42 ALTER TABLE [dbo].[User] ADD CONSTRAINT [DF_User_CreateUserId] DEFAULT ((0)) FOR [CreateUserId] 43 GO 44 45 ALTER TABLE [dbo].[User] ADD CONSTRAINT [DF_User_CreateDate] DEFAULT (getdate()) FOR [CreateDate] 46 GO 47 48 ALTER TABLE [dbo].[User] ADD CONSTRAINT [DF_User_UpdateUserId] DEFAULT ((0)) FOR [UpdateUserId] 49 GO 50 51 ALTER TABLE [dbo].[User] ADD CONSTRAINT [DF_User_UpdateDate] DEFAULT (getdate()) FOR [UpdateDate] 52 GO 53 54 ALTER TABLE [dbo].[User] ADD CONSTRAINT [DF_User_IsDeleted] DEFAULT ((0)) FOR [IsDeleted] 55 GO 56 57 EXEC sys.sp_addextendedproperty @name=N‘MS_Description‘, @value=N‘主鍵Id‘ , @level0type=N‘SCHEMA‘,@level0name=N‘dbo‘, @level1type=N‘TABLE‘,@level1name=N‘User‘, @level2type=N‘COLUMN‘,@level2name=N‘Id‘ 58 GO 59 60 EXEC sys.sp_addextendedproperty @name=N‘MS_Description‘, @value=N‘用戶名‘ , @level0type=N‘SCHEMA‘,@level0name=N‘dbo‘, @level1type=N‘TABLE‘,@level1name=N‘User‘, @level2type=N‘COLUMN‘,@level2name=N‘UserName‘ 61 GO 62 63 EXEC sys.sp_addextendedproperty @name=N‘MS_Description‘, @value=N‘密碼‘ , @level0type=N‘SCHEMA‘,@level0name=N‘dbo‘, @level1type=N‘TABLE‘,@level1name=N‘User‘, @level2type=N‘COLUMN‘,@level2name=N‘Password‘ 64 GO 65 66 EXEC sys.sp_addextendedproperty @name=N‘MS_Description‘, @value=N‘性別(0女,1男)‘ , @level0type=N‘SCHEMA‘,@level0name=N‘dbo‘, @level1type=N‘TABLE‘,@level1name=N‘User‘, @level2type=N‘COLUMN‘,@level2name=N‘Gender‘ 67 GO 68 69 EXEC sys.sp_addextendedproperty @name=N‘MS_Description‘, @value=N‘出生年月日‘ , @level0type=N‘SCHEMA‘,@level0name=N‘dbo‘, @level1type=N‘TABLE‘,@level1name=N‘User‘, @level2type=N‘COLUMN‘,@level2name=N‘Birthday‘ 70 GO 71 72 EXEC sys.sp_addextendedproperty @name=N‘MS_Description‘, @value=N‘創建人‘ , @level0type=N‘SCHEMA‘,@level0name=N‘dbo‘, @level1type=N‘TABLE‘,@level1name=N‘User‘, @level2type=N‘COLUMN‘,@level2name=N‘CreateUserId‘ 73 GO 74 75 EXEC sys.sp_addextendedproperty @name=N‘MS_Description‘, @value=N‘創建時間‘ , @level0type=N‘SCHEMA‘,@level0name=N‘dbo‘, @level1type=N‘TABLE‘,@level1name=N‘User‘, @level2type=N‘COLUMN‘,@level2name=N‘CreateDate‘ 76 GO 77 78 EXEC sys.sp_addextendedproperty @name=N‘MS_Description‘, @value=N‘更新人‘ , @level0type=N‘SCHEMA‘,@level0name=N‘dbo‘, @level1type=N‘TABLE‘,@level1name=N‘User‘, @level2type=N‘COLUMN‘,@level2name=N‘UpdateUserId‘ 79 GO 80 81 EXEC sys.sp_addextendedproperty @name=N‘MS_Description‘, @value=N‘更新時間‘ , @level0type=N‘SCHEMA‘,@level0name=N‘dbo‘, @level1type=N‘TABLE‘,@level1name=N‘User‘, @level2type=N‘COLUMN‘,@level2name=N‘UpdateDate‘ 82 GO 83 84 EXEC sys.sp_addextendedproperty @name=N‘MS_Description‘, @value=N‘標誌是否刪除(0未刪除,1已刪除)‘ , @level0type=N‘SCHEMA‘,@level0name=N‘dbo‘, @level1type=N‘TABLE‘,@level1name=N‘User‘, @level2type=N‘COLUMN‘,@level2name=N‘IsDeleted‘ 85 GO
2、添加對應的User表實體
1 /// <summary> 2 /// 用戶實體 3 /// </summary> 4 public class User : BaseModel 5 { 6 /// <summary> 7 /// 用戶名 8 /// </summary> 9 public string UserName { get; set; } 10 11 /// <summary> 12 /// 密碼 13 /// </summary> 14 public string Password { get; set; } 15 16 /// <summary> 17 /// 性別(0女,1男) 18 /// </summary> 19 public bool Gender { get; set; } 20 21 /// <summary> 22 /// 出生年月日 23 /// </summary> 24 public DateTime Birthday { get; set; } 25 }
3、使用泛型針對每一個表定義基本的CRUD接口,然後IUserRepository繼承它,如果需要其他的接口,後續往裏邊定義即可
1 /// <summary> 2 /// 基類業務接口定義 3 /// </summary> 4 public interface IBaseBusiness<T> where T : class 5 { 6 /// <summary> 7 /// 添加一個實體 8 /// </summary> 9 /// <param name="entity">要創建的實體</param> 10 /// <param name="connectionString">鏈接字符串</param> 11 /// <returns></returns> 12 bool CreateEntity(T entity, string connectionString = null); 13 14 /// <summary> 15 /// 根據主鍵Id獲取一個實體 16 /// </summary> 17 /// <param name="id">主鍵Id</param> 18 /// <param name="connectionString">鏈接字符串</param> 19 /// <returns></returns> 20 T RetriveOneEntityById(int id, string connectionString = null); 21 22 /// <summary> 23 /// 獲取所有實體 24 /// </summary> 25 /// <param name="connectionString">鏈接字符串</param> 26 /// <returns></returns> 27 IEnumerable<T> RetriveAllEntity(string connectionString = null); 28 29 /// <summary> 30 /// 修改一個實體 31 /// </summary> 32 /// <param name="entity">要修改的實體</param> 33 /// <param name="connectionString">鏈接字符串</param> 34 /// <returns></returns> 35 bool UpdateEntity(T entity, string connectionString = null); 36 37 /// <summary> 38 /// 根據主鍵Id刪除一個實體 39 /// </summary> 40 /// <param name="id">主鍵Id</param> 41 /// <param name="connectionString">鏈接字符串</param> 42 /// <returns></returns> 43 bool DeleteEntityById(int id, string connectionString = null); 44 }
4、主角進場。通過Nuget引入Dapper到Repository中,目前的版本為1.50.2
Install-Package Dapper
- Dapper是目前一款簡潔、高效並且開源的ORM(實體對象關系映射)框架之一。
傳送門:https://github.com/StackExchange/Dapper - 它不僅支持Sql Server,還適用於MySql,SqlLite,Oracle,PostgreSql等
- 默認使用參數化進行查詢或者新增
- 支持存儲過程
- 支持級聯映射和多表映射
- 默認緩沖你所執行的SQL
a)、設置你的鏈接字符串和DbConnection
1 /// <summary> 2 /// 數據庫配置 3 /// </summary> 4 public class DataBaseConfig 5 { 6 #region SqlServer鏈接配置 7 /// <summary> 8 /// 默認的Sql Server的鏈接字符串 9 /// </summary> 10 private static string DefaultSqlConnectionString = @"Data Source=.;Initial Catalog=Light;User ID=sa;Password=sa;"; 11 public static IDbConnection GetSqlConnection(string sqlConnectionString = null) 12 { 13 if (string.IsNullOrWhiteSpace(sqlConnectionString)) 14 { 15 sqlConnectionString = DefaultSqlConnectionString; 16 } 17 IDbConnection conn = new SqlConnection(sqlConnectionString); 18 conn.Open(); 19 return conn; 20 } 21 #endregion 22 }
b)、實現IUserRepository定義的接口,使用Dapper進行操作數據
1 /// <summary> 2 /// 用戶倉儲 3 /// </summary> 4 /// <typeparam name="User"></typeparam> 5 public class UserRepository : IUserRepository 6 { 7 /// <summary> 8 /// 創建一個用戶 9 /// </summary> 10 /// <param name="entity">用戶</param> 11 /// <param name="connectionString">鏈接字符串</param> 12 /// <returns></returns> 13 public bool CreateEntity(User entity, string connectionString = null) 14 { 15 using (IDbConnection conn = DataBaseConfig.GetSqlConnection(connectionString)) 16 { 17 string insertSql = @"INSERT INTO [dbo].[User] 18 ([UserName] 19 ,[Password] 20 ,[Gender] 21 ,[Birthday] 22 ,[CreateUserId] 23 ,[CreateDate] 24 ,[UpdateUserId] 25 ,[UpdateDate] 26 ,[IsDeleted]) 27 VALUES 28 (@UserName 29 ,@Password 30 ,@Gender 31 ,@Birthday 32 ,@CreateUserId 33 ,@CreateDate 34 ,@UpdateUserId 35 ,@UpdateDate 36 ,@IsDeleted)"; 37 return conn.Execute(insertSql, entity) > 0; 38 } 39 } 40 41 /// <summary> 42 /// 根據主鍵Id刪除一個用戶 43 /// </summary> 44 /// <param name="id">主鍵Id</param> 45 /// <param name="connectionString">鏈接字符串</param> 46 /// <returns></returns> 47 public bool DeleteEntityById(int id, string connectionString = null) 48 { 49 using (IDbConnection conn = DataBaseConfig.GetSqlConnection(connectionString)) 50 { 51 string deleteSql = @"DELETE FROM [dbo].[User] 52 WHERE Id = @Id"; 53 return conn.Execute(deleteSql, new { Id = id }) > 0; 54 } 55 } 56 57 /// <summary> 58 /// 獲取所有用戶 59 /// </summary> 60 /// <param name="connectionString">鏈接字符串</param> 61 /// <returns></returns> 62 public IEnumerable<User> RetriveAllEntity(string connectionString = null) 63 { 64 using (IDbConnection conn = DataBaseConfig.GetSqlConnection(connectionString)) 65 { 66 string querySql = @"SELECT [Id] 67 ,[UserName] 68 ,[Password] 69 ,[Gender] 70 ,[Birthday] 71 ,[CreateUserId] 72 ,[CreateDate] 73 ,[UpdateUserId] 74 ,[UpdateDate] 75 ,[IsDeleted] 76 FROM [dbo].[User]"; 77 return conn.Query<User>(querySql); 78 } 79 } 80 81 /// <summary> 82 /// 根據主鍵Id獲取一個用戶 83 /// </summary> 84 /// <param name="id">主鍵Id</param> 85 /// <param name="connectionString">鏈接字符串</param> 86 /// <returns></returns> 87 public User RetriveOneEntityById(int id, string connectionString = null) 88 { 89 using (IDbConnection conn = DataBaseConfig.GetSqlConnection(connectionString)) 90 { 91 string querySql = @"SELECT [Id] 92 ,[UserName] 93 ,[Password] 94 ,[Gender] 95 ,[Birthday] 96 ,[CreateUserId] 97 ,[CreateDate] 98 ,[UpdateUserId] 99 ,[UpdateDate] 100 ,[IsDeleted] 101 FROM [dbo].[User] 102 WHERE Id = @Id"; 103 return conn.QueryFirstOrDefault<User>(querySql, new { Id = id }); 104 } 105 } 106 107 /// <summary> 108 /// 修改一個用戶 109 /// </summary> 110 /// <param name="entity">要修改的用戶</param> 111 /// <param name="connectionString">鏈接字符串</param> 112 /// <returns></returns> 113 public bool UpdateEntity(User entity, string connectionString = null) 114 { 115 using (IDbConnection conn = DataBaseConfig.GetSqlConnection(connectionString)) 116 { 117 string updateSql = @"UPDATE [dbo].[User] 118 SET [UserName] = @UserName 119 ,[Password] = @Password 120 ,[Gender] = @Gender 121 ,[Birthday] = @Birthday 122 ,[UpdateUserId] = @UpdateUserId 123 ,[UpdateDate] = @UpdateDate 124 ,[IsDeleted] = @IsDeleted 125 WHERE Id = @Id"; 126 return conn.Execute(updateSql, entity) > 0; 127 } 128 } 129 }
上面的代碼所執行的方法Execute,Query,QueryFirstOrDefault其實都是IDbConnection的擴展方法,轉到定義你也可以清楚的看到默認buffered緩存是開啟的,並且都支持事務提交,同時還都對應各自的async異步方法
public static IEnumerable<T> Query<T>(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = default(int?), CommandType? commandType = default(CommandType?));
這樣一來,再也不用DataReader去一個一個屬性賦值了,也不用SqlParameter一個一個去參數化了,Dapper全部幫你做了,你只需要關註你的業務SQL語句以及上下文的對象即可,是不是很清爽!
c)、接下來就是完成對上一部分倉儲數據的調用。一方面是IBusiness的服務接口定義,另一方面則是Business的簡單實現,因為暫時只是涉及到一個表的增查改刪,所以具體的代碼就不上了
d)、至於依賴註入模塊,我直接使用的是Microsoft.Extensions.DependencyInjection,所有的服務由ServiceCollection服務容器進行管理,我們只需要將接口和它的實現類進行註冊就行了
1 /// <summary> 2 /// 註入業務邏輯層 3 /// </summary> 4 public class BusinessInjection 5 { 6 public static void ConfigureBusiness(IServiceCollection services) 7 { 8 services.AddSingleton<IUserBusiness, UserBusiness>(); 9 } 10 }
1 /// <summary> 2 /// 註入倉儲層 3 /// </summary> 4 public class RepositoryInjection 5 { 6 public static void ConfigureRepository(IServiceCollection services) 7 { 8 services.AddSingleton<IUserRepository, UserRepository>(); 9 } 10 }
三、引入SwaggerUI
簡介:SwaggerUI是一款針對WebApi的可視化工具,同樣我也稱它是一款全自動的接口描述文檔,並且可以很方便的幫助你測試你的接口,接下來我們一步一步的來把它添加進去。
1、向ASP.NET Core WebApi項目中添加Swashbuckle組件,打開包管理控制臺,輸入:
Install-Package Swashbuckle -Pre
記得加上後邊的-Pre,表示安裝最新版本,否則的話會默認下載穩定版本5.5.3(不支持Core)
當然了,你也可以包管理器進行安裝,記得勾選“包括預發行版”,然後選擇6.0.0-beta902進行安裝
2、打開Startup文件,添加Swagger中間件並將他們註入到應用程序的管道中,同時也將我們自定義的服務加進去
1 /// <summary> 2 /// This method gets called by the runtime. Use this method to add services to the container. 3 /// </summary> 4 /// <param name="services"></param> 5 public void ConfigureServices(IServiceCollection services) 6 { 7 RepositoryInjection.ConfigureRepository(services); 8 BusinessInjection.ConfigureBusiness(services); 9 services.AddMvc(); 10 services.AddSwaggerGen(); 11 } 12 13 /// <summary> 14 /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 15 /// </summary> 16 /// <param name="app"></param> 17 /// <param name="env"></param> 18 /// <param name="loggerFactory"></param> 19 public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 20 { 21 loggerFactory.AddConsole(Configuration.GetSection("Logging")); 22 loggerFactory.AddDebug(); 23 24 app.UseMvc(); 25 app.UseSwagger(); 26 app.UseSwaggerUi(); 27 }
3、打開launchSettings文件,修改launchUrl為“swagger/ui”
1 "profiles": { 2 "IIS Express": { 3 "commandName": "IISExpress", 4 "launchBrowser": true, 5 "launchUrl": "swagger/ui", 6 "environmentVariables": { 7 "ASPNETCORE_ENVIRONMENT": "Development" 8 } 9 }, 10 "Light.Api": { 11 "commandName": "Project", 12 "launchBrowser": true, 13 "launchUrl": "swagger/ui", 14 "environmentVariables": { 15 "ASPNETCORE_ENVIRONMENT": "Development" 16 }, 17 "applicationUrl": "http://localhost:62116" 18 } 19 }
4、添加一個UserController,針對每一個服務增加一個REST風格的API接口。註意使用的HttpMethod方法。HttpGet表示獲取對象,HttpPost表示創建對象,HttpPut表示修改對象,HttpDelete表示刪除對象
1 /// <summary> 2 /// 用戶控制器 3 /// </summary> 4 [Route("api/[controller]")] 5 public class UserController : Controller 6 { 7 private readonly IUserBusiness iUserBusiness; 8 /// <summary> 9 /// 構造函數註入服務 10 /// </summary> 11 /// <param name="userBusiness"></param> 12 public UserController(IUserBusiness userBusiness) 13 { 14 iUserBusiness = userBusiness; 15 } 16 17 /// <summary> 18 /// 獲取所有用戶 19 /// </summary> 20 /// <returns></returns> 21 [HttpGet] 22 //[Route("AllUser")] 23 public IEnumerable<User> GetAllUser() 24 { 25 return iUserBusiness.RetriveAllEntity(); 26 } 27 28 /// <summary> 29 /// 根據主鍵Id獲取一個用戶 30 /// </summary> 31 /// <param name="id">主鍵Id</param> 32 /// <returns></returns> 33 [HttpGet("{id}")] 34 public User GetOneUser(int id) 35 { 36 return iUserBusiness.RetriveOneEntityById(id); 37 } 38 39 /// <summary> 40 /// 新增用戶 41 /// </summary> 42 /// <param name="user">用戶實體</param> 43 /// <returns></returns> 44 [HttpPost] 45 public bool CreateUser([FromBody]User user) 46 { 47 return iUserBusiness.CreateEntity(user); 48 } 49 50 /// <summary> 51 /// 修改用戶 52 /// </summary> 53 /// <param name="id">主鍵Id</param> 54 /// <param name="user">用戶實體</param> 55 /// <returns></returns> 56 [HttpPut("{id}")] 57 public bool UpdateUser(int id, [FromBody]User user) 58 { 59 user.Id = id; 60 return iUserBusiness.UpdateEntity(user); 61 } 62 63 /// <summary> 64 /// 根據主鍵Id刪除一個用戶 65 /// </summary> 66 /// <param name="id">主鍵Id</param> 67 /// <returns></returns> 68 [HttpDelete("{id}")] 69 public bool DeleteUser(int id) 70 { 71 return iUserBusiness.DeleteEntityById(id); 72 } 73 }
5、大功告成,Ctrl+F5運行你的程序,並試著執行添加,修改和查詢的Api,體驗Swagger帶給你的方便之處。
寫在最後:這篇文章只是介紹了它們倆最簡單最基本的用法,如果其中說法有誤的,還望各位前輩多多指點,更多的內容還需要後續的繼續積累和學習,加油!
ASP.NET Core:使用Dapper和SwaggerUI來豐富你的系統框架