---
# System prepended metadata

title: '[範本] .Net Core Web API 建立流程'
tags: [泛型, Db First, Core, IRepository, WebAPI]

---

##  [範本] .Net Core Web API 建立流程
### 1. 安裝 Nuget 套件
- **Microsoft.EntityFrameworkCore.SqlServer**：會自動安裝 EntityFrameworkCore
- **Microsoft.EntityFrameworkCore.Tools**：可以操作 EF 套件管理器指令
### 2. DB First 套件管理器指令
- 使用最高權限
```text!
Scaffold-DbContext "Server=.;Database=DB_Name;Trusted_Connection=True;TrustServerCertificate=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models
```
- 使用帳號密碼
```text!
Scaffold-DbContext "Server=.;Database=DB_Name;User=YourUsername;Password=YourPassword;TrustServerCertificate=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models
```
### 3. Models.DbModel 進行註解 (繼承 DbContext 的檔案)
- 前往 DbModel.cs 註解`OnConfiguring`、`OnModelCreating`、`OnModelCreatingPartial`等方法
- 若使用 Code First，建立 DbModel Class 可參考：
```csharp=
public class DbModel:DbContext
{
    public DbModel(DbContextOptions<DbModel> options): base(options)
    {
    }
    public virtual // 創立的 Models 檔案=> DbSet<SubType> SubTypes { get; set; } 
    public virtual // 創立的 Models 檔案=> DbSet<MainType> MainType { get; set; }
}
```

### 4. Models 資料夾內部的其他 DbSet
- 加上 **\[Table("Table_Name")\]**、**\[Key\]**、**\[ForeignKey("FkAlbumid")\]**、**\[JsonIgnore\]**

### 5. Appsettings.json 新增連線字串

```javascript!
"AllowedHosts": "*",  // 這邊要加上，
"ConnectionStrings": {
"ConStr":"Server=.;Database=Db_Name;Trusted_Connection=True;TrustServerCertificate=True;"
}
```

### 6. 建立通用泛型介面 IRepository.cs 和實作介面類別 Repository.cs
- A. 根目錄**加入空資料夾 Data**，並於內部**加入 IRepository.cs**
```csharp!
public interface IRepository<TEntity> where TEntity : class
{
    Task<IEnumerable<TEntity>> GetAll();
    Task<TEntity> GetSingal(int id);
    Task Add(TEntity Enity);
    Task Update(TEntity Enity);
    Task Delete(int id);
}
```
- B. 根目錄資料夾 Data，於**內部加入 Repository.cs**
```csharp!
public class Repository<TEntity>:IRepository<TEntity> where TEntity : class
{
    private readonly //DbModel類別 or DbContext類別(會有問題) _context;
    private readonly DbSet<TEntity> _set;

    public Repository(//DbModel類別 or DbContext類別(會有問題) context)
    {
        _context = context;
        _set = context.Set<TEntity>();	
    }
    public async Task<IEnumerable<TEntity>> GetAll()
    {
        return await _set.ToListAsync();
    }

    public async Task<TEntity> GetSingal(int id)
    {
        return await _set.FindAsync(id);
    }

    public async Task Add(TEntity entity)
    {
        _set.Add(entity);
        await _context.SaveChangesAsync();
    }

    public async Task Update(TEntity entity)
    {
        _context.Entry(entity).State = EntityState.Modified;
        await _context.SaveChangesAsync();
    }

    public async Task Delete(int id)
    {
        var entity = await _context.Set<TEntity>().FindAsync(id);
        _set.Remove(entity);
        await _context.SaveChangesAsync();
    }
}
```
### 7. Program.cs 增加 DbContext 和 Scoped 的 Services
```csharp!
//var builder = WebApplication.CreateBuilder(args);

builder.Services.AddDbContext<PracticeAlbumSystemContext>(option => option.UseSqlServer(builder.Configuration.GetConnectionString("ConStr")));
builder.Services.AddScoped(typeof(IRepository<>), typeof(Repository<>));

//builder.Services.AddControllers();

//var app = builder.Build();
```
### 8. 於 Controllers 資料夾中，加入 API 控制器-空白(左側可以選擇)
```csharp!
[ApiController]
[Route("api/[controller]")]
public class AlbumController : ControllerBase
{
    private readonly IRepository<AlbumSystem> _albumRepository;
    private readonly IRepository<photo> _photoRepository;
    private readonly DbModel _db;

    // 可以使用多的不同類別的參數，透過 DI 注入加入，其中包含 DbModel
    public AlbumController(IRepository<AlbumSystem> albumRepository,
            IRepository<photo> photoRepository, DbModel db)
    {
        _albumRepository = albumRepository,
        _photoRepository = photoRepository,
        _db = db
    }

    [Route("GetAll")]
    public async Task<IActionResult> Index()
    {
        var allAlbumData = await _albumRepository.GetAll();
        return Ok(allAlbumData); // Json 格式回傳
    }
    
    [Route("GetPhoto")]
    public async Task<IActionResult> IndexPhoto()
    {
        var allAlbumData = await _albumRepository.GetAll();
        var firstMainType = allAlbumData.FirstOrDefault();
        // 啟動積極載入
        await _db.Entry(firstMainType)
              .Collection(u => u.SubType)
              .LoadAsync();

        var data = new
        {
            a = firstMainType.SubType.FirstOrDefault().Id
        };
        
        // 可以透過主表的虛擬欄位取得附表的資料
        return Ok(data); // Json 格式回傳
    }
}
```

