---
# System prepended metadata

title: .NET Core(Patel)
tags: [ASP.NET core, Udemy]

---

# .NET Core(Patel)

> Udemy課程：[.NET Core MVC - The Complete Guide 2024 [E-commerce] [.NET8]](https://www.udemy.com/course/complete-aspnet-core-21-course/?couponCode=KEEPLEARNING)

`20240706~`
:::danger

:::

# .NET Core(Patel)第 1 節：Welcome & Getting Started
## 1-14. Launch Settings
專案中properties > launchSettings.json，作為設定檔，例如跑debug時用https去跑，會導到哪一個URL

![image](https://hackmd.io/_uploads/ryURiXLwC.png)

****

## 1-15. wwwroot and appsettings
專案中wwwroot檔案放置各種靜態文件，例如CSS、JS、package或第三方函式庫(e.g. bootstrap、jquery etc.)。

![image](https://hackmd.io/_uploads/SkUZlE8vC.png)

專案中appsettings.json > appsettings.Development.json檔案，會放一些connecting string跟一些secret Key(e.g. DB 的secrete key)。

我們可以注意到這裡叫做appsettings.Development.json，當我們想deploy這個產品時，通常會再建立一個appsettings.Production.json檔案，並且至先前提到的properties > launchSettings.json中作如下方的修改：

```csharp!
// 修改前
"environmentVariables": {
  "ASPNETCORE_ENVIRONMENT": "Development"
}

// 修改後
"environmentVariables": {
  "ASPNETCORE_ENVIRONMENT": "Production"
}
```

這個時候程式碼就會知道，那些關於secrete Key的設定，就可以到appsettings.Production.json檔案尋找。

****

## 1-17. MVC Architecture

底下為我們為MVC架構所設定的pattern，可以從program.cs檔案找到。
![image](https://hackmd.io/_uploads/BJUoMEUwA.png)

****

## 1-22. Go Easy on Yourself!

* **Without Dependency Injection**
    * 原先
        ![image](https://hackmd.io/_uploads/SJEbbSUPR.png)

    * 若想修改DB class，那麼幾個page，就得修改幾次
        ![image](https://hackmd.io/_uploads/BkWLWBIwA.png)

* **With Dependency Injection**
    * 原先
        ![image](https://hackmd.io/_uploads/HkYtZH8DC.png)

    * 現在想做修改，只需修改DB 或 Email利用interface創建的class 實例即可，因為傳入到page使用的都是interface（設計藍圖，尚未實作的）
        ![image](https://hackmd.io/_uploads/rkNZfBIvC.png)

****

# .NET Core(Patel)第 2 節：Category CRUD Operations
## 2-24. Data Annotations
* 一般來說，Id就是作為資料庫Table中的Primary Key，而這裡的table為Category Table。
    `Models > Category.cs`
    ![image](https://hackmd.io/_uploads/rkJgsB8wC.png)

* 但是有可能我現在想把Id命名為Category__Id，這個時候我們就得用內建的namespace 叫做Data Annotaion，來做標記告知程式碼我的Category__Id就是我的Primary Key，用法就是在Category__Id class上一行填上"[Key]"（記得是大寫K）
    `Models > Category.cs`
    ![image](https://hackmd.io/_uploads/S1hcjS8wA.png)

* 另外一個Data Annotaion的用途就是，有時我們的table一些屬性，希望為必須存在，不應該為null值，那麼我們就可以利用Data Annotaion中的"[Required]"，同樣放在需要為Required的欄位class的前一行
    `Models > Category.cs`
    ![image](https://hackmd.io/_uploads/BJ_k6r8vR.png)


但我們如何真實的去建立Table呢？這還需要定義connection string來連接SQL server，還需要configure我們的程式來使用EF core(Entity Framework)跟SQL server。

****

## 2-25. Connection String

首先得確保已經下載好MSSQL，把下載步驟另外寫成一份[文件](https://hackmd.io/@noz915/BJfPhPDwR)了，接著要定義connection string，而要定義的位置在appsettings.json，並加上以下內容：

```csharp!
"ConnectionStrings": {
  "DefaultConnection": "Server=LAPTOP-8VM0NRAP;Database=Bulky;Trusted_Connection=True;TrustServerCertificate=True"
}
```
![image](https://hackmd.io/_uploads/Sy0UboPvC.png)


**Server**對應到的即SSMS中伺服器名稱。
![image](https://hackmd.io/_uploads/Hy5KTdvwC.png)

**Database**就是你想為這個資料庫取名為甚麼，那這裡就叫做Bulky。

****

## 2-26. Nuget Packages for Entity Framework Core
有了connection string後，接著就要在SQL server中建立資料庫了，不過在使用資料庫，我們希望可以利用EF core，所以接下來就要來設定些關於EF core相關的東西。

* 先對"BulkyWeb"點右鍵。
    ![image](https://hackmd.io/_uploads/SJu3eFDv0.png)

* 跑出選單後，選擇"Manage NuGet Packages..."
    ![image](https://hackmd.io/_uploads/H1BZWYPv0.png)

* 按"Browse"的部分，可以看到許多可以下載的套件（記得勾選"include prerelease"），這邊選擇"Microsoft.EntityFrameworkCore"。
    ![image](https://hackmd.io/_uploads/B1fZzFPDR.png)

* 點擊"Microsoft.EntityFrameworkCore"後，可以看到右側出現"install"，按下"install"下載。
    ![image](https://hackmd.io/_uploads/B1x2zFvw0.png)

* 另外我們也會用到SQL server，所以另外一個EFcore也得下載
    ![image](https://hackmd.io/_uploads/ByUL7Ywv0.png)

* 第三個要下載的是"Microsoft.EntityFrameworkCore.Tools"
    ![image](https://hackmd.io/_uploads/BJir4KwwR.png)

* 都下載好之後，我們可以從"installed"看見我們安裝好的套件。
    ![image](https://hackmd.io/_uploads/HykANtDvA.png)

* 除此之外，我們也可以從"BulkyWeb"程式中看見我們下載好的套件。
    ![image](https://hackmd.io/_uploads/S1kLrFwP0.png)

****

## 2-27. Setup ApplicationDbContext
我們新增好我們需要的NuGet Packages了，接下來要設置connection來連接我們的Database與EF core了。

* 首先，先建立一個資料夾叫做"Data"，"Data"資料夾裡面新增一個class叫做"ApplicationDbContext.cs"。
    ![image](https://hackmd.io/_uploads/HkZIwYwDC.png)

* 那接下來的設置，都是關於EF core最基本的設置
    * DbContext是EF core中的root class，當加在ApplicationDbContext class後方後，即代表我們的ApplicationDbContext class現在可以從DbContext class繼承或實作了。
        `Data > ApplicationDbContext.cs`
        ```csharp!
        using Microsoft.EntityFrameworkCore;

        namespace BullkyWeb.Data
        {
            public class ApplicationDbContext: DbContext
            {
            }
        }
        ```
        ![image](https://hackmd.io/_uploads/SJEcuYvw0.png)

    * 接下來需要將我們的connection string 傳入DbContext class的建構子中。
        `Data > ApplicationDbContext.cs`
        ```csharp!
        using Microsoft.EntityFrameworkCore;

        namespace BullkyWeb.Data
        {
            public class ApplicationDbContext: DbContext
            {
                public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
                {

                }
            }
        }
        ```
        ![image](https://hackmd.io/_uploads/Byc1jFDvR.png)
        
        稍微用chatGPT整理一下這幾行code的意思
        ![image](https://hackmd.io/_uploads/H14aL9PP0.jpg)
        
        然後是建構子與class的關係：
        ![image1](https://hackmd.io/_uploads/SyhaLqPPC.jpg)

        也就是說我們在"ApplicationDbContext"建構子中針對options做了任何的配置，都可以傳入我們的DbContext裡面。
        
        接著問題是我們要將"ApplicationDbContext"這個class在哪裡register？
        
        當我們想要register某些東西時，基本上都是到"Program.cs"這個檔案中做設定。
        
    * 所以開啟"Program.cs"，填上以下程式碼來告訴我們的application：「我們要使用EF core」。
        `Program.cs`
        ```csharp!
        using BullkyWeb.Data;
        using Microsoft.EntityFrameworkCore;

        builder.Services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))
        );
        ```
        ![image](https://hackmd.io/_uploads/rkxup5DPC.png)

****

## 2-28. Create Database
前面提到要建立資料庫，需要依靠EF core來完成設置，那前面基本上已經完成大多數的建置了，接下來就要打開SSMS來建立實際的資料庫了。

* 先確定SSMS已經連線上所選的伺服器，應該會長底下那樣，至於怎麼連接，可以參考這篇[筆記](![image](https://hackmd.io/_uploads/r1N9R5DvR.png)
)。
    ![image](https://hackmd.io/_uploads/ByG2AqwvC.png)

* 接著回到visual studio，按照"tools > NuGet Package Manager > Package Manager Console"，打開。
    ![image](https://hackmd.io/_uploads/B1BWkjvvR.png)

* 在底下打開的console打下
    ```
    update-database
    ```
    ![image](https://hackmd.io/_uploads/Bk2qZsDDC.png)

* 當它出現Done後，我們回到SSMS介面，將物件總管給重整，再次打開資料庫資料夾，便可以看到我們新增的Bulky資料庫了。
    ![image](https://hackmd.io/_uploads/B17HMsvPA.png)

****

## 2-29. Create Category Table
在這一節中，我們將可以看到EF core的power！在上一節中，我們已經成功建立Bulky資料庫，接下來我們希望將[2-24. Data Annotations](https://hackmd.io/@noz915/B10tqmIv0#2-24-Data-Annotations)中建立的"Models > Category.cs"這個檔案實作到資料庫中，在Bulky資料庫中建立一個 Category table（資料表）。

* 在我們的專案中，管理或操作資料庫的檔案即為"ApplicationDbContext.cs"，因為在這個檔案中使用到了DbContext，而DbContext便是使用到了EF core。

    那麼要如何在"ApplicationDbContext.cs"中實作「在Bulky資料庫中建立一個 Category table」這件事呢？

    當我們想要建立一個table時，就會在DbContext底下運用到一個關鍵字"DbSet"（從此處顯而易見可知DbSet也是由EF core套件提供的一個class）。
    
    `Data > ApplicationDbContext.cs`
    ```csharp!
    using BullkyWeb.Models;
    using Microsoft.EntityFrameworkCore;

    namespace BullkyWeb.Data
    {
        public class ApplicationDbContext: DbContext
        {
            public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
            {

            }

            public DbSet<Category> Categories { get; set; } // 主要這行幫我們建table
        }
    }

    ```
    ![image](https://hackmd.io/_uploads/r1N7uhvP0.png)

* 為了要建立table，我們還需要做些動作，叫做「migration（遷移）」（遷移是一種資料庫的版本控制，讓團隊能夠輕鬆的修改跟共享應用程式的資料庫結構。）

    遷移結構：一個遷移類別會包含兩個方法：up 和 down。up 方法用於在資料庫內增加新的資料表、欄位、或索引，而 down 方法則必須簡單的反向執行 up 方法的操作。
    
    > 參考資料：[DAY8 --- Laravel資料庫遷移(migration)](https://ithelp.ithome.com.tw/articles/10220189)
    > 參考資料：[Laravel 入門：認識 Migration](https://simonallen.coderbridge.io/2020/09/24/laravel-migration-note/)

    那在ASP.NET中如何實作migration？
    
    * 先打開"tools > NuGet Package Manager > Package Manager Console"後，在console中打上：
        ```
        add-migration AddCategoryTableToDb
        ```
        ![image](https://hackmd.io/_uploads/Sk8Ip3Dv0.png)
        
    * 執行完後，會看到我們專案中多了一個資料夾Migration，裏頭有剛建立的Migration
        ![image](https://hackmd.io/_uploads/ry896nwPA.png)

    * 那可以打開"20240707070034_AddCategoryTableToDb.cs"這個檔案，可以看見裡面有些程式碼，而這些程式碼便是EF core用他的語言所撰寫而成的，也就是用來建立Category Table的程式碼。

        我們可以看看其中的一小部分：
        ![image (1)](https://hackmd.io/_uploads/Sy7qkTwDC.jpg)
        
        以及前面提過的Up & Down 方法：
        ![image](https://hackmd.io/_uploads/H1Q8W6wDC.png)

    * 當我們建立好migration之後，要記得回到"Package Manager Console"中對資料庫打上"update-database"做更新。
        ```
        update-database
        ```
        ![image](https://hackmd.io/_uploads/BJx1XpwDR.png)
    
        那它是如何做到更新的呢？
        
        其實當我們執行"update-database"時，程式會去看我們最新建立的migration，然後取該migration中的程式碼，將這些程式碼轉成相對應的SQL語法來建立table（以此處提及的migration為例）。
        
        我們也能從SMSS中的"dbo.\_MigrationsHistory"表格中看到剛剛update database時，它apply的migration是哪一個。
        ![image](https://hackmd.io/_uploads/SJWs7pPv0.png)

* ### 對這節做一個總結：如何建立Table？
    1. 建立Model，Model包含一些屬性作為Table的欄位：
        `Models > Category.cs`
        ![image](https://hackmd.io/_uploads/HkXyUTPwC.png)

    2. ApplicationDbCaontext檔案中，在DbContext底下使用DbSet：
        `Data > ApplicationDbCaontext.cs`
        ![image](https://hackmd.io/_uploads/r127IaDw0.png)
    3. 到manager package console中輸入：
        ```
        add-migration
        ```
    4. 新增好migration後，在manager package console中輸入以下內容便可以將migration push到我們的資料庫裡面了：
        ```
        update-database
        ```
    5. 1~4步驟完成後，我們就可以在我們的Bulky資料庫中看到Category這張table了。

****

## 2-30. Add Category Controller
