---
# System prepended metadata

title: EF Core
tags: [.NET Core, EntityFramework]

---

# EF Core
## 前置作業
### 一、 安裝套件
```csharp=
Microsoft.EntityFrameworkCore.Design
Microsoft.EntityFrameworkCore.Tools
Microsoft.EntityFrameworkCore.SqlServer
```
### 二、 設定連線字串
```csharp=
  "ConnectionStrings": {
    "DefaultConnection": "Server=.;Initial Catalog=Test;User Id=id;Password=pw;MultipleActiveResultSets=True;TrustServerCertificate=true"
  },
```
## Code First
### 一、 建立Model
建立Custome與Order的Model，Customer中的`ICollection<Order>`關聯表示一個客有多筆訂單，FK為Order.CustomerId。
```csharp=
public class Customer
{
    public int CustomerId { get; set; }
    public string Name { get; set; }
    public ICollection<Order> Orders { get; set; }
}

public class Order
{
    public int OrderId { get; set; }
    public DateTime OrderDate { get; set; }
    public decimal Amount { get; set; }
    public int CustomerId { get; set; }
    public Customer Customer { get; set; }
}
    
```
### 二、 建dbContext
```csharp=
public class myDbContext : DbContext
{
    public myDbContext(DbContextOptions<myDbContext> options) : base(options)
    {}
    public DbSet<Customer> Custmer { get; set; }
    public DbSet<Order> Order { get; set; }
}
```
### 三、 注入服務
```csharp=
builder.Services.AddDbContext<myDbContext>(options =>
{
     options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"));
});
```
### 四、 Migrations
#### (一) 新增資料庫移轉設定
- 建立資料庫移轉設定
```csharp=
dotnet ef migrations add init
```

如果出現`您打算執行 .NET 程式，但 dotnet-ef 不存在。`的錯誤，先執行下面的安裝指令
```
dotnet tool install --global dotnet-ef
```
- 移除資料庫移轉設定檔案
會移除最後一個migrations檔案，但會先比會資料庫，如果已update會無法移除
```csharp=
dotnet ef migrations remove
```
#### (二) 更新資料庫
##### 1. 建立Model至db
 - 更新最新版本
```csharp=
dotnet ef database update -v  //套用到最新版本
```
- 指定版本
```csharp=
dotnet ef database update <to>
dotnet ef database update init //migrations名稱，不含時間
```
- 下完指令之後就會在db上建立Table了
![image](https://hackmd.io/_uploads/rJSjaZlJR.png)

- 關聯如同Model所設計
![image](https://hackmd.io/_uploads/H1ZT6ZekA.png)

##### 2. 建立新Model並更新至db
- 一樣先建立Model
```csharp=
Public class Goods{
    public int GoodsId{get;set;}
    public string GoodName {get;set;}
}
```
- 加入至dbContenxt
```csharp=
public class myDbContext : DbContext
{
    public myDbContext(DbContextOptions<myDbContext> options) : base(options)
        {}
    public DbSet<Customer> Custmer { get; set; }
    public DbSet<Order> Order { get; set; }
    public DbSet<Goods> Goods { get; set; }
}
```
- 資料庫移轉設定
```csharp=
dotnet ef migrations add Add_Goods
```
- 更新至db
```csharp=
dotnet database update
```
執行完就會順利建立Table了
![image](https://hackmd.io/_uploads/r1LKzGeJC.png)
##### 3. 更新欄位
- 修改名稱長度，加上Attribute`[StringLength(30)]`
```csharp=
public class Goods
{
    public int GoodsId { get; set; }
    [StringLength(30)]
    public string GoodName { get; set; }
}
```
- 建立migrations檔案
```csharp=
dotnet ef migrations add Edit_Goods
```
- 更新至db
```csharp=
dotnet ef database update
//指定版本
dotnet ef database update <TO>
dotnet ef database update Edit_Goods
```
如果指定的<Edit_Goods>版本為第3版的話，執行後會更新0~3版。
執行完之後順利更新為nvarchar(30)了
![image](https://hackmd.io/_uploads/S1pc4zgkR.png)

##### 4. db預設值設定
- 修改Goods model，新增一欄位`CreateDate`紀錄資料寫入時間
```csharp=
public class Goods
{
    public int GoodsId { get; set; }
    [StringLength(30)]
    public string GoodName { get; set; }
    public DateTime CreateDate {get;set;}
}
```
- 產生Migrations
```csharp=
dotnet ef migrations add Add_Goods_CreateDate
```
- 修改migrations檔案，在`defaultValueSql`中加入`GETDATE()`，如果是其他資料庫的話就改為對應的語法
```csharp=
    migrationBuilder.AddColumn<DateTime>(
        name: "CreateDate",
        table: "Goods",
        type: "datetime2",
        nullable: false,
        defaultValueSql:"GETDATE()"
        );
```
- 更新資料庫
```csharp=
dotnet ef database update -v
```
完成預設值設定
![image](https://hackmd.io/_uploads/HJP_cXe10.png)


#### (三) 降版
- 回複所有設定
```csharp=
dotnet ef database update 0
```
- 或指定特定的版本就可完成降版
```csharp=
dotnet ef database update <TO>
```
#### (四) 產生sql指令碼

```csharp=
dotnet ef migrations script -o output.sql
```
- 指定要產出的版本
```csharp=
dotnet ef migrations script <FROM> <TO> -o output.sql

//FROM為0表示從最早的版本開始
dotnet ef migrations script 0 Add_Goods -o output.sql
```

#### (五) 刪除資料庫

```csharp=
dotnet ef database drop
```
