.Net Core Web Api_笔记24_api结合EFCore资料库操作part2_产品分类资料新增_资料查询呈现(带入非同步API修饰)

接续上一篇

在Startup.cs中启用静态资源
於专案新增目录命名为wwwroot(会自动变成地球的图示)

https://ithelp.ithome.com.tw/upload/images/20220113/201074523oUhhs8Tpr.png

对wwwroot去进行
引入bs4跟jquery3.6
测试Client端有UI时的互动存取(透过jQuery)
https://ithelp.ithome.com.tw/upload/images/20220113/20107452aOFUgSB7Vd.png

https://ithelp.ithome.com.tw/upload/images/20220113/20107452Co4aVhcdOu.png

https://ithelp.ithome.com.tw/upload/images/20220113/20107452M2YPgnWlfh.png

https://ithelp.ithome.com.tw/upload/images/20220113/20107452xu5aJz3LaE.png
接着要实作
产品分类资料查询与增加
新增PCategoryController.cs和对应的新增Action及查询Action
~\Controllers\PCategoryController.cs

同步形式的API存取

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Net5EFCoreWebApiApp.Data;
using Net5EFCoreWebApiApp.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Net5EFCoreWebApiApp.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class PCategoryController : ControllerBase
    {        
        //Startup.cs中注册EF服务後,就可在特定控制器藉由.net core预设DI,透过建构子去实践存取ProductDbContext。
        private readonly ProductDbContext _dbContext;
        public PCategoryController(ProductDbContext dbContext)
        {
            _dbContext = dbContext;
        }

        [HttpPost("Add")]
        public ActionResult<int> AddProductCategory(PCategory pCategory)
        {
            if (pCategory == null)
                return NotFound();

            if (string.IsNullOrEmpty(pCategory.CTitle))
                return NotFound();

            pCategory.CId = Guid.NewGuid();
            _dbContext.PCategories.Add(pCategory);
            int RowCount = _dbContext.SaveChanges();
            return CreatedAtAction(nameof(AddProductCategory),RowCount);
        }

        [HttpGet("Show")]
        public ActionResult<List<PCategory>> ShowProductCategory()
        {
            var categories = _dbContext.PCategories.ToList();
            return categories;
        }

    }
}

透过.net core DI我们在建构子注入DbContext就能在整个Controller程序中进行存取异动

新增对应静态资源页面

~\wwwroot\PCategory\Add.html

<!DOCTYPE html>
<html>
<head>
    <title>Add ProductType</title>
    <link href="../css/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
    <script src="../js/jquery/jquery.min.js"></script>
</head>
<body>
    <div style="padding:20px;border:1px solid #0094ff;width:600px;margin:30px;">
        <h3>产品类别</h3>
        <hr />
        <div class="form-horizontal">
            <div class="form-group col-4">
                <label>产品类别</label>
                <input type="text" class="form-control" id="CategoryTitle">
            </div>
            <div class="form-group">
                <div class="col-md-2 col-md-10">
                    <button type="submit" id="btnSubmit" class="btn btn-primary">Submit</button>
                </div>
                <div>
                    <span id="msg" class="danger"></span>
                </div>
            </div>
        </div>
    </div>

    <script type="text/javascript">
        $('#btnSubmit').click(function () {
            $.ajax({
                type: 'post',
                url: "/api/pcategory/add",
                dataType: "text",
                data: JSON.stringify({                    
                    CTitle: $('#CategoryTitle').val()
                }),
                contentType: 'application/json',
                success: function (result) {
                    if (result == "1") {
                        $('#msg').text('成功添加');
                    }
                }
            });
        });
    </script>
</body>
</html>

~\wwwroot\PCategory\Show.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
    <link href="../css/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
    <script src="../js/jquery/jquery.min.js"></script>
</head>
<body style="margin:20px;">
    <table id="tbProductCategory" class="table table-bordered">
        <thead>
            <tr>
                <td>产品类别ID</td>
                <td>产品类别名称</td>                
            </tr>
        </thead>
        <tbody>
        </tbody>
    </table>

    <script type="text/javascript">
        $(function () {
            var tbody = $('#tbProductCategory tbody');
            $.ajax({
                type: 'get',
                url: '/api/pcategory/show',
                dataType: 'json',
                success: function (result) {
                    $.each(result, function (n, value) {
                        var tr_val = "";
                        tr_val += "<tr><td>" + value.cId
                            + "</td><td>" + value.cTitle
                            + "</td></tr>";
                        tbody += tr_val;
                    });
                    $('#tbProductCategory').append(tbody);
                }
            });
        });
    </script>

</body>
</html>

运行效果

https://ithelp.ithome.com.tw/upload/images/20220113/20107452jpvUPK8EIT.png

https://ithelp.ithome.com.tw/upload/images/20220113/20107452IXPFtJGLjy.png

而在过去用ado.net搭配写法或者上述写法
基本上都是采用同步的API存取方式
所以基本上单位时间内能处理消化的请求量或称为「吞吐(流通)量Throughput」有限
因此会有阻塞问题

由於EFCore有支援异步存取的相关API(方法名Async後缀)
这里可以再改为非同步的API存取

非同步(异步)形式的API存取

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Net5EFCoreWebApiApp.Data;
using Net5EFCoreWebApiApp.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Net5EFCoreWebApiApp.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class PCategoryController : ControllerBase
    {        
        //Startup.cs中注册EF服务後,就可在特定控制器藉由.net core预设DI,透过建构子去实践存取ProductDbContext。
        private readonly ProductDbContext _dbContext;
        public PCategoryController(ProductDbContext dbContext)
        {
            _dbContext = dbContext;
        }

        [HttpPost("Add")]
        public async Task<ActionResult<int>> AddProductCategory(PCategory pCategory)
        {
            if (pCategory == null)
                return NotFound();

            if (string.IsNullOrEmpty(pCategory.CTitle))
                return NotFound();

            pCategory.CId = Guid.NewGuid();
            _dbContext.PCategories.Add(pCategory);
            int RowCount = await _dbContext.SaveChangesAsync();
            return CreatedAtAction(nameof(AddProductCategory),RowCount);
        }

        [HttpGet("Show")]
        public async Task<ActionResult<List<PCategory>>> ShowProductCategory()
        {
            var categories = await _dbContext.PCategories.ToListAsync();
            return categories;
        }

    }
}

Ref:

The Ultimate Guide to Async and Await in C# and ASP.NET
https://exceptionnotfound.net/async-await-in-asp-net-csharp-ultimate-guide/

[效能调教] 使用 Async / Await 非同步机制加快 Web API 回应时间
https://dotblogs.com.tw/wasichris/2017/06/08/101137#%E7%B5%90%E8%AB%96

网站测试工具-JMeter教学
https://www.astralweb.com.tw/website-test-tool-jmeter-teaching/

JMeter-网页压力测试教学
https://www.astralweb.com.tw/jmeter-website-stress-testing-tutorial/

.NET Web应用中为什么要使用async/await异步编程
https://www.cnblogs.com/xhznl/p/13064731.html

为什麽需要使用非同步程序设计,真的可以提升整体应用程序的执行效能吗?
https://csharpkh.blogspot.com/2019/07/Asynchronous-ThreadPool-programming-synchronous-NET-Core-Framework-async-await.html

ASP.NET async 基本心法
https://blog.darkthread.net/blog/async-aspnet/

本篇已同步发表至个人部落格
https://coolmandiary.blogspot.com/2022/01/net-core-web-api24apiefcorepart2api.html


<<:  .Net Core Web Api_笔记23_api结合EFCore资料库操作part1_专案前置准备

>>:  .Net Core Web Api_笔记25_api结合EFCore资料库操作part3_产品分类资料的编辑与删除(EF的更新写法怎麽这麽多种!如何观察EF产生的SQL)

Day27_CSS语法10

border-width(框线宽度) 宽度的设定值有:thin(细)、medium(中)、thick...

【左京淳的Spring学习笔记】基础案例

使用首页、输入画面、输出画面等三个基础画面,来熟悉画面之间跳转及资料移动的原理。 本练习不涉及业务...

找LeetCode上简单的题目来撑过30天啦(DAY3)

各位中秋节连假愉快,我今天坐客运,还包车了呢,司机先生只载我一个人,运气不错,好啦今天也要继续努力解...

Hello, OS!

资料传输 常见的资料传输方式有两种: Serial 将一串资料拆成多个资料,一次传一个资料。 pro...

Day12. Class Method 与 MetaClass 的观念

昨天提到的实体方法,是为了创建的物件提供方法使用,而与实体方法相对的另一个方法叫类别方法,是类别本身...