ASP.NET Core Web API と Entity Framework Core で SQL Server からデータを取得する

#はじめに



こういうテーブルから

|BookId  |Title |Author |
|:-:|:--|:--|
|1  |たったひとつの冴えたやり方|ジェイムズ・ティプトリー・ジュニア|
|2  |アンドロイドは電気羊の夢を見るか?|フィリップ・K・ディック|
|3  |夏への扉|ロバート・A. ハインライン|
|4  |幼年期の終り|アーサー C クラーク|
|5  |われはロボット|アイザック・アシモフ|

こういう JSON を返す API を作る。

```json
[
	{
		"bookId": 1,
		"title": "たったひとつの冴えたやりかた",
		"author": "ジェイムズ・ティプトリー・ジュニア"
	},
	{
		"bookId": 2,
		"title": "アンドロイドは電気羊の夢を見るか?",
		"author": "フィリップ・K・ディック"
	},
	{
		"bookId": 3,
		"title": "夏への扉",
		"author": "ロバート・A. ハインライン"
	},
	{
		"bookId": 4,
		"title": "幼年期の終り",
		"author": "アーサー C クラーク"
	},
	{
		"bookId": 5,
		"title": "われはロボット",
		"author": "アイザック・アシモフ"
	}
]
```

### 環境

- Visual Studio 2019
- .NET Core 2.2

# プロジェクト作成

新しいプロジェクトの作成。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/383318/c5751f89-7869-013f-8675-9bedd218da83.png)

ASP.NET Core Web アプリケーション。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/383318/103cb010-4419-dec0-4d5b-f87090e9420e.png)

プロジェクト名を指定。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/383318/8d1200d3-cf83-a8a4-3b00-5b8480313310.png)

API を選択して作成。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/383318/e9dd9b24-cca7-e3c1-fcbb-2ba41cdd11bb.png)

# コーディング

まずはエンティティクラスを作成する。プロジェクト直下に `Entities` フォルダーを追加。`Entities` フォルダーに `Book` クラスを追加。

```csharp:Entities/Book.cs
namespace SimpleWebApi.Entities
{
    public class Book
    {
        public int BookId { get; set; }
        public string Title { get; set; }
        public string Author { get; set; }
    }
}
```

次にエンティティクラスとテーブルをマッピングするためのコンテキストクラスを作成する。プロジェクト直下に `Data` フォルダーを追加。`Data` フォルダーに `DbContext` クラスを継承した `BookContext` クラスを追加。

```csharp:Data/BookContext.cs
using Microsoft.EntityFrameworkCore;
using SimpleWebApi.Entities;

namespace SimpleWebApi.Data
{
    public class BookContext : DbContext
    {
        public BookContext(DbContextOptions options) : base(options)
        {
        }

        public DbSet<Book> Books { get; set; }
    }
}
```

`Controllers` フォルダーに `BooksController` コントローラーを追加。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/383318/bc136106-0d10-8e79-da6a-fec4b7064607.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/383318/3d0809f7-14e7-4ff2-352d-f95c70add4dc.png)

コントローラーにコンストラクターと `List` メソッドを追加。

```csharp:Controllers/BooksController.cs
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using SimpleWebApi.Data;
using SimpleWebApi.Entities;

namespace SimpleWebApi.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class BooksController : ControllerBase
    {
        private readonly BookContext context;

        public BooksController(BookContext context)
        {
            this.context = context;
        }

        [HttpGet]
        public ActionResult<IEnumerable<Book>> List()
        {
            var books = context.Books;
            return books;
        }
    }
}
```

Startup.cs にコンテクストクラスをサービスとして登録する。

```csharp:Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using SimpleWebApi.Data;

namespace SimpleWebApi
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<BookContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); //追加
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseMvc();
        }
    }
}

```

appsettings.json に接続文字列を追加。

```json:appsettings.json
{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=SimpleWebApiDb;Trusted_Connection=True;"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*"
}
```

# データ準備

パッケージマネージャーコンソールで以下のコマンドを実行。（`Migrations` フォルダーと Migration クラスが作成される）

```powershell
> Add-Migration Initial
```

続けて以下のコマンドを実行。（データベースとテーブルが作成される）

```powershell
> Update-Database
```

SQL Server でレコード追加クエリ実行。

```sql
INSERT INTO Books (Title, Author) VALUES (N'たったひとつの冴えたやりかた',N'ジェイムズ・ティプトリー・ジュニア');
INSERT INTO Books (Title, Author) VALUES (N'アンドロイドは電気羊の夢を見るか?',N'フィリップ・K・ディック');
INSERT INTO Books (Title, Author) VALUES (N'夏への扉',N'ロバート・A. ハインライン');
INSERT INTO Books (Title, Author) VALUES (N'幼年期の終り',N'アーサー C クラーク');
INSERT INTO Books (Title, Author) VALUES (N'われはロボット',N'アイザック・アシモフ');
```

# 動作確認

デバッグ実行して /api/books にアクセス。

```json
[
    {
        "bookId": 1,
        "title": "たったひとつの冴えたやりかた",
        "author": "ジェイムズ・ティプトリー・ジュニア"
    },
    {
        "bookId": 2,
        "title": "アンドロイドは電気羊の夢を見るか?",
        "author": "フィリップ・K・ディック"
    },
    {
        "bookId": 3,
        "title": "夏への扉",
        "author": "ロバート・A. ハインライン"
    },
    {
        "bookId": 4,
        "title": "幼年期の終り",
        "author": "アーサー C クラーク"
    },
    {
        "bookId": 5,
        "title": "われはロボット",
        "author": "アイザック・アシモフ"
    }
]
```

# ソースコード
https://github.com/tamtamyarn/SimpleWebApi

# 続き
[ASP.NET Core Web API で CRUD & Swagger/OpenAPI でテスト](https://qiita.com/tamtamyarn/items/71dec4e747a9a523b24f)