2024年12月15日 星期日

【.Net Core】 EF Core + Web API 實作


 EF Core是Entity Framework在.Net Core使用的版本,功能幾乎相同,但具有輕巧、高擴充性以及高效能等優點,建議各位學習。


通常在.Net Core如果要用ORM的方式會有兩種選擇分別是EF Core以及Dapper。

從其他網路文章可以看到這兩種在最新版的效能其實都很接近了,只是定位有點不同,以下列出我目前覺得他們的定位導向(如有錯誤歡迎打臉指正我)

EF Core:適用於簡易查詢,有 Migrations、LINQ Support以及Lazy loading等等優點

Dapper:適用於簡易查詢以及複雜查詢(各種Join或Union),原因是複雜查詢用T-SQL難度較低於用LINQ的EF Core。

網路文章提供的功能比較圖


從以上兩點可以看到其實可以在一個專案同時使用兩種不同的方式去使用各自的優點。

例如Rico大大提到的使用EF Core 的Code First跟Migration,Dapper則拿來用複雜Query(or store procedures)

那就廢話不多說,開始來實作玩玩看

這次標的為 .Net 6 Web API + EF Core 7


首先先建立專案(範例都用預設,有其他需求再自行調整)


建立完透過Nuget安裝以下Package

2024年8月21日 星期三

[React]開發常見問題

 


此篇文章記錄一下一些初學者開發React時比較常見的一些問題。

(2024/08/22 更新)


2024年3月22日 星期五

[jest]Software Testing

 

此篇要教各位如何去撰寫前端的測試流程,測試在CI/CD流程內是不可或缺的一環

例如下方的pipeline圖




開始前先來了解一下主要會使用到的元件
  • jest-environment-jsdom一般也指測試的執行環境(environment),目的是模擬瀏覽器的行為、API,讓開發者能在 Node.js 的環境下模擬瀏覽器的操作
  • jest:是一個用來執行 JavaScript 測試的框架(JavaScript Test Framework),又稱 test runner,它讓開發者能夠執行測試、撰寫斷言,提供的 API 像是 expect、describe、test、toBe、toEqual 等等。其他這類的 JS testing frameworks 如 Vitest、mochajs、Jasmine 等等
  • @testing-library/jest-dom:原本 Jest 就有提供許多不同的 matchers(例如,toBe()、toEqual()等等),@testing-library/jest-dom則是擴充了更多可以在 Jest 中使用的 matchers,讓開發者可以使用toBeInTheDocument()` 等這類和 DOM 有關的 matchers。
  • @testing-library/react:基於 @testing-library/dom,它讓開發者可以把 React 元件 render 到 DOM 上,像是 render、screen、rerender、unmount 等等。不需要搭配 Jest 才能使用。其他這類的工具如 Enzyme。
  • @testing-library/user-event:模擬使用者的操作來測試使用者與 UI 的互動。相較於 @testing-library/dom 中的 fireEvent 更能模擬使用者的行為。
  • @babel/plugin-transform-modules-commonjs:ESM轉譯成CJS的套件,如果有使用到第三方套件則必須載入。

了解套件後就可以開始設定專案

先安裝套件,可透過以下語法安裝

2024年2月21日 星期三

[Gitlab]CI-流程建置

 

CI(Continuous Integration)是Devops的軟體開發流程,主要針對程式碼變更後的自動建置和測試之後,定期將變更合併置主要Repository,CI的關鍵目標是能更快發現和解決問題、改善軟體品質還有減少驗證和釋出軟體更新所需的時間。


此篇文章將教你如何建立Gitlab CI流程

環境說明:

  • Gitlab (self-managed)
  • Gitlab Runner
  • Docker (windows)


首先在Docker上安裝Gitlab-Runner,輸入以下指令安裝Docker

2024年2月16日 星期五

[React]環境部署


透過以下的簡易步驟,來部署React網站


以下依照不同的Server列出說明

項次

部署位置

地端/雲端

部署方式

說明

1

Windows Server(iis)

手動

本地VM,測試環境或者待管Server時會使用

2

Azure

手動

透過VS CodeFTP去部署

3

Azure

自動

透過CI/CD方式去部署

 

 

 

 

 


  • Window Server(iis)

1.先設定iis站台的URL Rewrite (SPA網站都可參考此設定)

//Web.config

更多資訊可參考保哥此篇文章說明

2.使用Terminal執行語法npm run build,以產生實體檔(檔案預設放在dist

3.手動搬移檔案至Server

  •  Azure (手動上傳)

    手動上傳還可區分成VS Code部署以及FTP部署兩種

    • VS Code部署

  1. 安裝Azure App Service Extension
  2. 使用語法npm run build產生實體檔(檔案預設放在dist資料夾)
  3. 使用滑鼠右鍵對選dist資料夾中的Deploy to Web App…
  4.  點選Sign in Azure
  5. 選擇登入Azure帳號
  6. 登入成功後選擇建立Azure App Service段落所建立App Service
  7. 點選Deploy以部署到 App Service
  8. 佈署成功可點選右下角的Browse WebSite查看(須過一段時間才能正常顯示)

    • FTP部署

  1. 使用語法npm run build產生實體檔(檔案預設放在dist資料夾)
  2. AzureApp Service頁面點選左側的Deployment center
  3.  點選FTP credentials就可以看到FTP的連線設定
  4. 使用FTP工具(.Filezilla)連線並將欲部署的檔案更新上去。

  •  Azure (CI/CD)
因CI/CD會被SourceControl的不同影響,待有實作時再回補說明


 













[React] 開發環境建立

  


依據以下步驟建立React開發環境,本篇文章使用的是vite來建立專案,而不是之前介紹的CRA。


先新建一個專案資料夾,並透過VS Code開啟


用Ctrl+`來開啟Terminal,並輸入以下Command

npm create vite@latest

再根據專案選項依序點選





接著用OpenFolder的方式開啟剛剛建立的專案資料夾


用Ctrl+`開啟Terminal,輸入以下指令安裝package.json內的相依套件

npm install

 安裝完成後,再輸入以下指令就可以偵錯網站

npm run dev


點擊網址,就可以看到網頁囉






2023年1月30日 星期一

[React]實作自定義的Component(密碼輸入框)

 


這篇主要說明如何開發自定義的Component,讓多個頁面都可同時使用,範例程式碼可參考這裡


最常見的自定義元件大概就是輸入框、讀取動畫或視窗...這類的。因為之前有實作過登入頁,那就以密碼輸入框來教大家如何實作。

因示範專案使用的是MUI,建議各位在開發任何元件前都可確認有沒有官方範例,有的話就可以省下大量的時間去實作。

而這功能確實有找到官方範例,那就可以直接抓程式碼下來使用!


首先先在src/components/text裡新增Password.tsx,並將官方範例貼上去。

Password.tsx

----------------------------------------------------------------------------------------------------------------

import { Visibility, VisibilityOff } from "@mui/icons-material";
import { IconButton, InputAdornment, TextField } from "@mui/material";
import { useState } from "react";
export default function Password(props: passwordProps) {
    //顯示密碼Flag
    const [showPassword, setShowPassword] = useState(false);
    //眼睛點選事件
    const handleClickShowPassword = () => setShowPassword((show) => !show);
    //取消預設點選事件
    const handleMouseDownPassword = (event: React.MouseEvent<HTMLButtonElement>) => {
        event.preventDefault();
    };
    return (
        <TextField
            error={props.ErrorMsg !== ''}
            margin="normal"
            required
            fullWidth
            name={props.Name}//"password"
            label={props.Label}//"Password"
            id={props.ID}//"password"
            autoComplete="current-password"
            helperText={props.ErrorMsg !== '' ? props.ErrorMsg : ""}
            InputProps={{
                type: showPassword ? 'text' : 'password',
                endAdornment:
                    <InputAdornment position="end" >
                        <IconButton
                            aria-label="toggle password visibility"
                            onClick={handleClickShowPassword}
                            onMouseDown={handleMouseDownPassword}
                            edge="end"
                        >
                            {showPassword ? <VisibilityOff /> : <Visibility />}
                        </IconButton>
                    </InputAdornment>
            }
            }
        />
    );
}
interface passwordProps {
    ID:string
    Name: string
    Label:string
    ErrorMsg?: string;
}

----------------------------------------------------------------------------------------------------------------


主要定義幾個屬性

ID:元件ID。
Name:元件Name,有包Form的可透過FormData.get({name})抓到值。
Label:元件Label。
ErrorMsg:顯示錯誤訊息。 

 

再將Login的原先密碼欄位改成使用<Password/>

Login.tsx

----------------------------------------------------------------------------------------------------------------

import Password from '../components/text/Password';

省略...

{/*原程式碼*/}
{/*<TextField*/}
{/*    error={LoginMsg !== ''}*/}
{/*    margin="normal"*/}
{/*    required*/}
{/*    fullWidth*/}
{/*    name="password"*/}
{/*    label={t('Login.Password')}*/}
{/*    type="password"*/}
{/*    id="password"*/}
{/*    autoComplete="current-password"*/}
{/*    helperText={LoginMsg !== '' ? LoginMsg:""}*/}
{/*/>*/}
 <Password ID="password" Name="password" Label={t('Login.Password')} ErrorMsg={LoginMsg} />

省略...

----------------------------------------------------------------------------------------------------------------


這樣就完成囉,未來如果有需要使用密碼欄位就可以同Login頁載入使用,下面Demo一下效果

初始為不顯示密碼

點選眼睛,就可以看到剛輸入的密碼。


看起來功能正常,這樣大家就可以開始來製作屬於自己的元件囉!


這篇功能感覺比前幾篇簡單許多,其實是各位在之前的教學都已經有作過了,讓大家猜猜看是什麼?


公布答案!其實各個頁面也是Component,只是載入的地方在APP.tsx內且透過React-Router去切換掉Content,所以如果有多個地方要顯示同樣的頁面,也可以使用此篇教的方法囉!















【.Net Core】 EF Core + Web API 實作

 EF Core是Entity Framework在.Net Core使用的版本,功能幾乎相同,但具有輕巧、高擴充性以及高效能等優點,建議各位學習。 通常在.Net Core如果要用ORM的方式會有兩種選擇分別是EF Core以及Dapper。 從其他網路文章可以看到這兩種在最新...