List TaskItem(記憶體):重新啟動後,新增資料會消失
taskflow-ef.db(SQLite):儲存在磁碟中,重新啟動後仍能讀取

一樣使用昨日專案
using TaskFlow3.Api.Models;
namespace TaskFlow3.Api.Services
{
public interface ITaskService
{
Task<List<TaskItem>> GetAllAsync();
Task<TaskItem?> GetByIdAsync(int id);
Task<TaskItem> CreateAsync(string title);
Task<bool> UpdateAsync(
int id,
string title,
bool isCompleted);
Task<bool> DeleteAsync(int id);
}
}
using Microsoft.EntityFrameworkCore;
using TaskFlow3.Api.Data;
using TaskFlow3.Api.Models;
namespace TaskFlow3.Api.Services
{
public class TaskService : ITaskService
{
private readonly TaskFlowDbContext _db;
// 透過 DI 取得 DbContext
public TaskService(TaskFlowDbContext db)
{
_db = db;
}
// GET:查詢所有任務
public async Task<List<TaskItem>> GetAllAsync()
{
return await _db.Tasks.ToListAsync();
}
// GET:依 Id 查詢
public async Task<TaskItem?> GetByIdAsync(int id)
{
return await _db.Tasks.FindAsync(id);
}
// POST:新增任務
public async Task<TaskItem> CreateAsync(string title)
{
TaskItem task = new TaskItem
{
Title = title,
IsCompleted = false
};
await _db.Tasks.AddAsync(task);
await _db.SaveChangesAsync();
return task;
}
// PUT:修改任務
public async Task<bool> UpdateAsync(
int id,
string title,
bool isCompleted)
{
TaskItem? task = await _db.Tasks.FindAsync(id);
if (task == null)
{
return false;
}
task.Title = title;
task.IsCompleted = isCompleted;
await _db.SaveChangesAsync();
return true;
}
// DELETE:刪除任務
public async Task<bool> DeleteAsync(int id)
{
TaskItem? task = await _db.Tasks.FindAsync(id);
if (task == null)
{
return false;
}
_db.Tasks.Remove(task);
await _db.SaveChangesAsync();
return true;
}
}
}
using Microsoft.EntityFrameworkCore;
using TaskFlow3.Api.Data;
using TaskFlow3.Api.Services;
var builder = WebApplication.CreateBuilder(args);
// OpenAPI
builder.Services.AddOpenApi();
// Controller
builder.Services.AddControllers();
builder.Services.AddScoped<ITaskService, TaskService>();
string dbPath = Path.Combine(
builder.Environment.ContentRootPath,
"taskflow-ef.db"
);
builder.Services.AddDbContext<TaskFlowDbContext>(options =>
options.UseSqlite($"Data Source={dbPath}")
);
var app = builder.Build();
// 開發環境才啟用 OpenAPI 和 Swagger UI
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint("/openapi/v1.json", "v1");
});
}
app.UseHttpsRedirection();
// 啟用 Controller 路由
app.MapControllers();
// 測試路由
app.MapGet("/test", () => "伺服器正常運作!");
app.MapGet("/db-check", async (TaskFlowDbContext db) =>
{
var tasks = await db.Tasks.ToListAsync();
return Results.Ok(tasks);
});
app.Run();
using Microsoft.AspNetCore.Mvc;
using TaskFlow3.Api.DTOs;
using TaskFlow3.Api.Models;
using TaskFlow3.Api.Services;
namespace TaskFlow3.Api.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class TasksController : ControllerBase
{
private readonly ITaskService _taskService;
public TasksController(ITaskService taskService)
{
_taskService = taskService;
}
// GET /api/tasks
[HttpGet]
public async Task<ActionResult<List<TaskDto>>> GetTasks()
{
var tasks = await _taskService.GetAllAsync();
var result = tasks.Select(t => ToDto(t)).ToList();
return Ok(result);
}
// GET /api/tasks/1
[HttpGet("{id:int}")]
public async Task<ActionResult<TaskDto>> GetTask(int id)
{
TaskItem? task = await _taskService.GetByIdAsync(id);
if (task == null)
{
return NotFound("找不到這筆任務");
}
return Ok(ToDto(task));
}
// POST /api/tasks
[HttpPost]
public async Task<ActionResult<TaskDto>> CreateTask(
[FromBody] CreateTaskDto input)
{
if (input == null ||
string.IsNullOrWhiteSpace(input.Title))
{
return BadRequest("任務名稱不可空白");
}
TaskItem task =
await _taskService.CreateAsync(input.Title);
return CreatedAtAction(
nameof(GetTask),
new { id = task.Id },
ToDto(task)
);
}
// PUT /api/tasks/1
[HttpPut("{id:int}")]
public async Task<IActionResult> UpdateTask(
int id,
[FromBody] UpdateTaskDto input)
{
if (input == null ||
string.IsNullOrWhiteSpace(input.Title))
{
return BadRequest("任務名稱不可空白");
}
bool success = await _taskService.UpdateAsync(
id,
input.Title,
input.IsCompleted
);
if (!success)
{
return NotFound("找不到這筆任務");
}
return NoContent();
}
// DELETE /api/tasks/1
[HttpDelete("{id:int}")]
public async Task<IActionResult> DeleteTask(int id)
{
bool success = await _taskService.DeleteAsync(id);
if (!success)
{
return NotFound("找不到這筆任務");
}
return NoContent();
}
// Model 轉成 DTO
private static TaskDto ToDto(TaskItem task)
{
return new TaskDto
{
Id = task.Id,
Title = task.Title,
IsCompleted = task.IsCompleted
};
}
}
}
結果
在 VS Code 終端機執行:dotnet build,接著執行:dotnet run