NEWS

[dotNet5.0] Web API - MSSQL Server - Dapper

[dotNet5.0] Web API - MSSQL Server - Dapper
Đăng bởi: TONA Cody - Lượt xem: 4682 15:19:30, 05/10/2021C#   In bài viết

Hế lồ mọi ngừi,  
Covi thật sự không muốn rời xa, "theo tình tình chạy" còn Covi thì đuổi mãi không đi. Thời gian này khá là rảnh rỗi, nên hôm nay mình sẽ hướng dẫn các bạn tạo ra một Web API xịn xò con cò viết bằng ngôn ngữ Net Core phiên bản 5.0 nhé.
Ví dụ này khá là cơ bản, tuy nhiên cũng không kém phần chuyên nghiệp, cấu trúc rõ ràng, và các bạn hoàn toàn có thể sử dụng để làm nền tảng cho các dự án NetCore sử dụng SQL luôn.

Web API with DotNet 5.0 using MSSQL and Dapper - Github

LaptrinhVB hiện đã có khá nhiều bài viết về Dapper, có lẽ mọi người cũng không còn xa lạ gì nữa.
Trong bài viết này, mình đã vận dụng SQLHelper class của a Thảo Meo, đồng thời có một số chỉnh sửa nhất định cho phù hợp với dự án Net Core.

Nhắc cũng khá nhiều cụm từ NetCore rồi, vậy Vì sao lại sử dụng NetCore ?

  • Bởi vì chúng ta có căn bản về C#, hầu hết hàm, lệnh trong NetFramework đều có thể sử dụng ở trong NetCore, đó là một lợi thế đối với các bạn đang theo học C#. Hơn nữa, với NetCore, bây giờ chúng ta có thể xây dựng ứng dụng webserver chạy trên các nền tảng khác chứ không còn bó buộc với Windows nữa v.v... Và cuối cùng là, chúng ta thích. :D

Để tìm hiểu kỹ hơn, các bạn Google hộ mình nhé.

Các bạn nên vào trang chủ của Microsoft để xem qua để có thể khái quát cách hoạt động của một API NetCore. Hiện tại, nhóm đã có đầu tư hơn về chi tiết của Netcore, sau đó hẵng quay lại bài này, vì bài này hơi 18+, và hơn hết là trang chủ không chỉ chúng ta xài Dapper đâu :3.

Project Github

Bắt đầu nào:

Chúng ta cần phải cài dotnet để có thể code và chạy ứng dụng này. Cài SQL Server để có thể sử dụng database.

Đầu tiên là cấu trúc thư mục mình sẽ hướng đến: Controllers, Models, DTOs, Repositories, Settings and Helpers.

Tiếp theo: Mở Visual studio Code lên, Ctrl + ~ để mở Terminal và gõ câu lệnh để thử tạo 1 webapi cho mình để test:

dotnet new webapi -n <tên-ứng-dụng>

1. Nếu cài thành công, bạn hãy tải source (source ở cuối bài viết) của mình về, giải nén và mở ra bằng Visual studio Code. Sau đó cài sẵn các thư viện SQLClient và Dapper vào:

dotnet add package System.Data.SqlClient

dotnet add package Dapper

dotnet add package Dapper.Contrib

2. Như vậy là đầy đủ các thư viện cần thiết rồi, mở Microsoft SQL Server management Studio lên và excute tập tin này để tạo ra database cho ứng dụng (hoặc không cần thiết nếu bạn đã sẵn có database):

--Open this file in Microsoft SQL Server Management Studio
--And Press Excute button above
    
IF NOT EXISTS(SELECT * FROM sys.databases WHERE name = 'DEMO_DB')
  BEGIN
    CREATE DATABASE DEMO_DB


    END
    GO
       USE DEMO_DB
    GO
------------------------
---some common proc we used
CREATE  PROC [dbo].[sp_generate_class] @tableName varchar(200)
AS
BEGIN

declare @Result varchar(max) = 'public class ' + @TableName + '
{'

select @Result = @Result + '
    public ' + ColumnType + NullableSign + ' ' + ColumnName + ' { get; set; }
'
from
(
    select 
        replace(col.name, ' ', '_') ColumnName,
        column_id ColumnId,
        case typ.name 
            when 'bigint' then 'long'
            when 'binary' then 'byte[]'
            when 'bit' then 'bool'
            when 'char' then 'string'
            when 'date' then 'DateTime'
            when 'datetime' then 'DateTime'
            when 'datetime2' then 'DateTime'
            when 'datetimeoffset' then 'DateTimeOffset'
            when 'decimal' then 'decimal'
            when 'float' then 'double'
            when 'image' then 'byte[]'
            when 'int' then 'int'
            when 'money' then 'decimal'
            when 'nchar' then 'string'
            when 'ntext' then 'string'
            when 'numeric' then 'decimal'
            when 'nvarchar' then 'string'
            when 'real' then 'double'
            when 'smalldatetime' then 'DateTime'
            when 'smallint' then 'short'
            when 'smallmoney' then 'decimal'
            when 'text' then 'string'
            when 'time' then 'TimeSpan'
            when 'timestamp' then 'DateTime'
            when 'tinyint' then 'byte'
            when 'uniqueidentifier' then 'Guid'
            when 'varbinary' then 'byte[]'
            when 'varchar' then 'string'
            else 'UNKNOWN_' + typ.name
        end ColumnType,
        case 
            when col.is_nullable = 1 and typ.name in ('bigint', 'bit', 'date', 'datetime', 'datetime2', 'datetimeoffset', 'decimal', 'float', 'int', 'money', 'numeric', 'real', 'smalldatetime', 'smallint', 'smallmoney', 'time', 'tinyint', 'uniqueidentifier') 
            then '?' 
            else '' 
        end NullableSign
    from sys.columns col
        join sys.types typ on
            col.system_type_id = typ.system_type_id AND col.user_type_id = typ.user_type_id
    where object_id = object_id(@TableName)
) t
order by ColumnId

set @Result = @Result  + '
}'

PRINT  @Result
END
GO 
---------
CREATE  PROC [dbo].[USP_Lazy_GenerateParamester4Proc] @tableName VARCHAR(200)
AS
BEGIN
SELECT 

CASE 
	WHEN t.Name LIKE '%char' THEN 
	 '@' + c.name + ' ' + t.name + '(' +CAST(c.max_length AS VARCHAR(max))+ '),' 
	 ELSE
      '@' + c.name + ' ' + t.name + ','
END AS 'fullDatatype',

    c.name  as 'Column Name' ,

	'@' + c.name + ',' as N'Biến' ,

	  c.name + '=@' + c.name + ',' as N'Gán' ,

    t.Name 'Data type',
    c.max_length 'Max Length',
    c.precision ,
    c.scale ,
    c.is_nullable,
    ISNULL(i.is_primary_key, 0) 'Primary Key'
FROM    
    sys.columns c
INNER JOIN 
    sys.types t ON c.user_type_id = t.user_type_id
LEFT OUTER JOIN 
    sys.index_columns ic ON ic.object_id = c.object_id AND ic.column_id = c.column_id
LEFT OUTER JOIN 
    sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id
WHERE
    c.object_id = OBJECT_ID(@tableName)
END
GO 
------------------end-----
CREATE  proc [dbo].[USP_MakeResponse](@status varchar(50), @description nvarchar(1000), @jsonData nvarchar(max)='')
as
begin
	select @status Status, @description as Description,  @jsonData AS Data
END




--You need to check if the table exists
IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='tbl_users' and xtype='U')
BEGIN
	CREATE TABLE [dbo].[tbl_users](
		[id] [INT] IDENTITY(1,1) NOT NULL,
		[f_name] [NVARCHAR](50) NOT NULL,
		[l_name] [NVARCHAR](50) NOT NULL,
		[dob] [DATE] NULL,
		[email] [NVARCHAR](200) NULL,
		[phone] [VARCHAR](20) NULL,
		[created_date] [DATETIME] NULL,
		[created_user] [VARCHAR](50) NULL,
		[updated_date] [DATETIME] NULL,
		[updated_user] [VARCHAR](50) NULL,
	PRIMARY KEY CLUSTERED 
	(
		[id] ASC
	)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
	) ON [PRIMARY]

	ALTER TABLE [dbo].[tbl_users] ADD  DEFAULT (GETDATE()) FOR [created_date]

	INSERT INTO dbo.tbl_users
	(
		f_name,
		l_name,
		dob,
		email,
		phone,
		created_user
	)
	VALUES
	( 'TONA','DINH', '2021-01-01','dinhtona@gmail.com','84908697365', 'ROOT' ),
	( 'MEO','THAO', '2021-01-01','dinhtona@gmail.com','84908697365', 'ROOT' ),
	( 'KHANG','QUOC', '2021-01-01','dinhtona@gmail.com','84908697365', 'ROOT' ),
	( 'THAO','NGO', '2021-01-01','dinhtona@gmail.com','84908697365', 'ROOT' ),
	( 'MESSI','LEONEL', '2021-01-01','dinhtona@gmail.com','84908697365', 'ROOT' ),
	( 'RONALDO','CRITIANO', '2021-01-01','dinhtona@gmail.com','84908697365', 'ROOT' ),
	( 'NEYMAR','JR', '2021-01-01','dinhtona@gmail.com','84908697365', 'ROOT' )
END



SELECT * FROM dbo.tbl_users

GO
--------------------end common------------------------


CREATE PROC USP_User_Get @id VARCHAR(MAX)=''--@id=2 || '1,5,6,4,8, ...' || ''
AS
BEGIN
	SELECT * FROM tbl_users WHERE exists 
	(SELECT  value FROM STRING_SPLIT(IIF(ISNULL(@id,'')='', CONCAT(id,''), @id), ',')
	WHERE ltrim(rtrim(value)) = id)
END 

GO

--EXEC USP_User_Get '2,9'

CREATE  PROC USP_User_Save 
(
	@id int,
	@f_name varchar(100),
	@l_name varchar(100),
	@dob date,
	@username VARCHAR(50),
	@email varchar(200),
	@phone varchar(20)
)
AS
BEGIN
	DECLARE @isExists INT=0, @des NVARCHAR(1000)
	SELECT @isExists=COUNT(*) FROM tbl_users WHERE id=@id;
	IF(@isExists>0)
		BEGIN
			UPDATE dbo.tbl_users
			SET 
			f_name=@f_name,
			l_name=@l_name,
			dob=@dob,
			updated_user=@username,
			updated_date=GETDATE(),
			email=@email,
			phone=@phone
			WHERE id=@id;

			SET @des=CONCAT(N'Updated Successfully user: ', @f_name )
			EXEC dbo.USP_MakeResponse @status = 'OK',      -- varchar(50)
			                          @description = @des -- nvarchar(1000)
			
		END
	ELSE
		BEGIN
			INSERT INTO dbo.tbl_users
			(
			    f_name,
			    l_name,
			    dob,			    
			    created_user,
			    created_date,
			    email,
			    phone
			)
			VALUES
			(  @f_name,
				@l_name,				
				@dob,				
				@username,
				GETDATE(),
				@email,
				@phone
			 )

			SET @des=CONCAT(N'Added Successfully user: ', @f_name )
			EXEC dbo.USP_MakeResponse @status = 'OK',      -- varchar(50)
			                          @description = @des -- nvarchar(1000)
		END

END

GO

CREATE  PROC [dbo].[USP_User_Delete] @id INT
AS
BEGIN
	SET XACT_ABORT ON
	BEGIN TRAN
	BEGIN TRY
	   DELETE FROM dbo.tbl_users WHERE id=@id;	
	   
	   EXEC dbo.USP_MakeResponse @Status = 'OK',      -- varchar(50)
	                             @Description = N'Deleted !' -- nvarchar(1000)

	COMMIT
	END TRY
	BEGIN CATCH
	   ROLLBACK
	   DECLARE @ErrorMessage NVARCHAR(2000)
	   SELECT @ErrorMessage = N'Error: ' + ERROR_MESSAGE()
	   EXEC dbo.USP_MakeResponse @Status = 'ERROR',      -- varchar(5)
	                                  @Description =@ErrorMessage -- nvarchar(max)	   
	   --RAISERROR(@ErrorMessage, 16, 1)
	END CATCH
END
GO 

EXEC sp_generate_class 'tbl_users'
EXEC [USP_Lazy_GenerateParamester4Proc] 'tbl_users'
GO 
SELECT * FROM dbo.tbl_users
GO 

3. Thay đổi thông tin SQL Config cho đúng với thông tin trên SQL server của bạn ở file appsettings.json: Lưu ý: xóa các phần được chú thích đi:

{
  ...,
  "AllowedHosts": "*",

  "SQLSettings":{
    "Host":"localhost", //Server Instance
    "DBName":"DEMO_DB", //Database Name
    "User":"as" //user Login Server
    //Password: *** //password will be saved in secret
  }
}
4.  Khởi tạo giá trị cho password một cách bí mật. Visual code Terminal:

    
dotnet user-secrets init
dotnet user-secrets set SQLSettings:Password your_password_login_to_server

5.  Run with Visual code Terminal:

    
dotnet run
 

Mặc định api của mình sẽ online ở địa chỉ: 

https://localhost:5001/swagger/index.html

Hoặc bạn có thể sử dụng Postman để test với đường dẫn: https://localhost:5001/users

Download Fullsource

 

Cám ơn vì đã theo dõi bài viết !

HAPPY CODING ♡♡♡

THÔNG TIN TÁC GIẢ

BÀI VIẾT LIÊN QUAN

[dotNet5.0] Web API - MSSQL Server - Dapper
Đăng bởi: TONA Cody - Lượt xem: 4682 15:19:30, 05/10/2021C#   In bài viết

CÁC BÀI CÙNG CHỦ ĐỀ

Đọc tiếp
.