###### tags: `MVC`
# MVC Model
## 介紹
從.NET 3.5開始,.NET提供了概念模型(conceptual model)的 Entity Framework,概念模型可以根據資料庫(Database First)建立 Model 與資料庫的對應關係,並且存成 XML 檔案,副檔名為 EDMX,讓你可以有 GUI 來管理 Model,如下圖。

.NET4.0(EF4),推出了 Model First,可以先不用先有資料庫,而從概念模型定義 Model 是什麼,進而產生實體資料庫。EF4 提供了 Model First 跟 Database First 的方式來管理 Model,而用 Model First 與 Database First 都是需要用到 EDMX 來產生對應的 Model Class。
EF4同時也推出了新的管理 Model 的方式,稱為 Code First。使用 Code First 不需要有 EDMX來做 Model 的管理。沒有了EDMX,Code First 使用 POCO classes來定義 domain model。
Code First, Database First 和 Model First 都是為了使用 Entity Framework 建立 Entity Data Model 的方式。其實 Entity Framework 不管如何建立 Model,因為在有 Model 後,Entity Framework 在 runtime 所做的行為都是是一樣的。
無論是選擇 EDMX 來管理 Model 或者是 Code-based Modeling 來管理 Model 其實都是可以達成目的。根據下圖,可以了解之間的差別。

## Code First
### 新增 Model
在 Models 資料夾點擊滑鼠右鍵 → 加入 → 類別 → 選擇資料 → ADO.NET 實體資料模型

### 選擇空的 Code First 模型
自動在 Web.config 產生連線字串(預設為 Windows 驗證登入)

設定連線字串:
```xml=
<connectionStrings>
<add name="Model1" connectionString="data source=伺服器名稱;
initial catalog=資料庫名稱;
integrated security=True;
MultipleActiveResultSets=True;
App=EntityFramework" providerName="System.Data.SqlClient" />
</connectionStrings>
```
### 選擇來自資料庫的 Code First
自動在 Web.config 產生連線字串(選擇 SQL Server 驗證登入)

點擊「新增連接」

1. 輸入伺服器名稱
2. 選擇 SQL Server 驗證,輸入使用者名稱及密碼
3. 選取要連線的資料庫名稱

連接字串選項勾選「是,在連接字串中包含敏感性資料」

目前的資料庫是空的,所以不用選擇

完成後在 Models 資料夾會建立 `Model1.cs`

`Model1.cs`

新增 `Customer.cs` 及 `Address.cs`,而兩個 Model 就是對應到資料庫的兩個 Table。
* `Customer.cs`
```csharp=
public partial class Customer
{
public int Id { get; set; }
[Required]
[StringLength(50)]
public string Name { get; set; }
[Required]
[StringLength(50)]
public string Email { get; set; }
[StringLength(50)]
public string Tel { get; set; }
public GenderType? Gender { get; set; }
public DateTime? InitDate { get; set; }
public virtual ICollection<Address> Addresses { get; set; }
}
```
* `Address.cs`
```csharp=
public class Address
{
public int Id { get; set; }
public int CustomerId { get; set; }
[Required]
[StringLength(5)]
public string Zip { get; set; }
[Required]
[StringLength(5)]
public string City { get; set; }
[Required]
[StringLength(50)]
public string myAddress { get; set; }
public DateTime? InitDate { get; set; }
public virtual Customer Customers { get; set; }
}
```
在 `Modle1.cs` 加入 `Customer.cs` 和 `Address.cs`
```csharp=
public class Model1 : DbContext
{
public Model1() : base("name=Model1")
{
}
public virtual DbSet<Customer> Customers { get; set; }
public virtual DbSet<Address> Addresses { get; set; }
}
```
### 執行 database migration 指令
#### Step1. 選擇工具(Tools) → NuGet 套件管理員 → 套件管理主控台叫出 Package Manager Console。
#### Step2. 輸入 `Enable-Migrations`,會建立 Magrations 資料夾和`Configuration.cs`。
#### Step3. 接著輸入`Add-Migration [移轉名稱]`,產生資料庫變更記錄:`時間戳記_移轉名稱.cs`。
#### Step4. 接著輸入`Update-Database`,將內容更新到資料庫。
**如果類別有更動或是新增,只要重新執行`Add-Migration [移轉名稱]`與`Update-Database`指令**
> 參考資料
* [Code First 起手式](https://dotblogs.com.tw/mileslin/2016/07/28/184421)
* [使用Code First](https://dotblogs.com.tw/armycoding/2018/07/12/002730)
* [Entity framework code first](https://dotblogs.com.tw/dog0416/2016/04/06/110438)