ASP.NET core mysqlに接続してAPIを作成する

ASP.NET core mysqlに接続してAPIを作成する

ASP.NET coreでmysqlに接続してAPIを作成する順を記述してます。asp.coreのバージョンは「6」です。

環境

  • OS windows 10 pro
  • asp.core 6
  • mysql 8.0.27
  • visual stadio 2022

APIプロジェクト作成

まずはプロジェクトを作成します。「ASP.NET Core Web API」を選択します。

任意のプロジェクト名で作成します。

「.NET 6.0」を使用します。

Pomelo.EntityFrameworkCore.MySqlを使用

「mysql」を使用するために「Pomelo.EntityFrameworkCore.MySql」を使用します。

「ツール」 > 「NuGetパッケージマネージャー」>「ソリューションのNuGetパッケージの管理」を選択します。

「Pomelo.EntityFrameworkCore.MySql」で検索します。

インストールを実行します。

「OK」をクリックしてインストールを完了します。

Mysql

mysql側は、以下のテーブルを使用します。

CREATE TABLE `TestData` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(20) COLLATE utf8mb4_general_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci

「TestData」テーブル

Models作成

「Models」フォルダを作成して配下に「TestData.cs」を作成します。

「TestData.cs」

namespace mysqlSample.Models
{
    public class TestData
    {
        public long Id { get; set; }
        public string Name { get; set; }
    }
}

コンテキストの追加します。「TestContext.cs」と言う名前で作成します。

「TestContext.cs」

using Microsoft.EntityFrameworkCore;

namespace mysqlSample.Models
{
    public class TestContext : DbContext
    {
        public TestContext(DbContextOptions<TestContext> options) : base(options)
        {
        }

        public DbSet<TestData> TestData { get; set; }
    }
}

「Models」フォルダ配下は以下のようになります。

Program.cs

「Program.cs」に接続情報などやコンテキストの登録を記述しておきます。

using Microsoft.EntityFrameworkCore;
using mysqlSample.Models;

var builder = WebApplication.CreateBuilder(args);

var connectionString = "server=localhost;user=testuser;password=password;database=foo";

var serverVersion = new MySqlServerVersion(new Version(8, 0, 27));
// Add services to the container.

builder.Services.AddControllers();

builder.Services.AddDbContext<TestContext>(
            dbContextOptions => dbContextOptions
                .UseMySql(connectionString, serverVersion)                
                .LogTo(Console.WriteLine, LogLevel.Information)
                .EnableSensitiveDataLogging()
                .EnableDetailedErrors()
        );


var app = builder.Build();

// Configure the HTTP request pipeline

app.UseAuthorization();

app.MapControllers();

app.Run();

Controllerのスキャフォールディング

Controllerにスキャフォールディングを追加します。

「追加」> 「新規スキャフォールディングアイテム」を選択します。

「Entity Frameworkを使用したアクションがあるAPIコントローラー」を選択して「追加」をクリックします。

controllerを作成します。

controllerが作成されます。

#nullable disable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using mysqlSample.Models;

namespace mysqlSample.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class TestDatasController : ControllerBase
    {
        private readonly TestContext _context;

        public TestDatasController(TestContext context)
        {
            _context = context;
        }

        // GET: api/TestDatas
        [HttpGet]
        public async Task<ActionResult<IEnumerable<TestData>>> GetTestData()
        {
            return await _context.TestData.ToListAsync();
        }

        // GET: api/TestDatas/5
        [HttpGet("{id}")]
        public async Task<ActionResult<TestData>> GetTestData(long id)
        {
            var testData = await _context.TestData.FindAsync(id);

            if (testData == null)
            {
                return NotFound();
            }

            return testData;
        }

        // PUT: api/TestDatas/5
        // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
        [HttpPut("{id}")]
        public async Task<IActionResult> PutTestData(long id, TestData testData)
        {
            if (id != testData.Id)
            {
                return BadRequest();
            }

            _context.Entry(testData).State = EntityState.Modified;

            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!TestDataExists(id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }

            return NoContent();
        }

        // POST: api/TestDatas
        // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
        [HttpPost]
        public async Task<ActionResult<TestData>> PostTestData(TestData testData)
        {
            _context.TestData.Add(testData);
            await _context.SaveChangesAsync();

            return CreatedAtAction("GetTestData", new { id = testData.Id }, testData);
        }

        // DELETE: api/TestDatas/5
        [HttpDelete("{id}")]
        public async Task<IActionResult> DeleteTestData(long id)
        {
            var testData = await _context.TestData.FindAsync(id);
            if (testData == null)
            {
                return NotFound();
            }

            _context.TestData.Remove(testData);
            await _context.SaveChangesAsync();

            return NoContent();
        }

        private bool TestDataExists(long id)
        {
            return _context.TestData.Any(e => e.Id == id);
        }
    }
}

実行

実行するとAPIが利用できることが確認できます。

別テーブルから取得

別のテーブル「sample」からもデータを取得してみます。

「sample」テーブル

「Sample.cs」

using System;
using System.ComponentModel.DataAnnotations;

namespace mysqlSample.Models
{
    public class Sample
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public DateTime Created_at { get; set; }
    }
}

「TestContext.cs」に「Sample」を追加します。

using Microsoft.EntityFrameworkCore;

namespace mysqlSample.Models
{
    public class TestContext : DbContext
    {
        public TestContext(DbContextOptions<TestContext> options) : base(options)
        {
        }

        public DbSet<TestData> TestData { get; set; }

        public DbSet<Sample> sample { get; set; }
    }
}

「Program.cs」は同じです。

using Microsoft.EntityFrameworkCore;
using mysqlSample.Models;


var builder = WebApplication.CreateBuilder(args);

var connectionString = "server=192.168.100.42;user=testuser;password=password;database=foo";

var serverVersion = new MySqlServerVersion(new Version(8, 0, 27));
// Add services to the container.

builder.Services.AddDbContext<TestContext>(
            dbContextOptions => dbContextOptions
                .UseMySql(connectionString, serverVersion)                
                .LogTo(Console.WriteLine, LogLevel.Information)
                .EnableSensitiveDataLogging()
                .EnableDetailedErrors()
        );

builder.Services.AddControllers();

var app = builder.Build();

// Configure the HTTP request pipeline


app.UseAuthorization();

app.MapControllers();

app.Run();

同様に「SamplesController.cs」を作成します。

「SamplesController.cs」

#nullable disable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using mysqlSample.Models;

namespace mysqlSample.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class SamplesController : ControllerBase
    {
        private readonly TestContext _context;

        public SamplesController(TestContext context)
        {
            _context = context;
        }

        // GET: api/Samples
        [HttpGet]
        public async Task<ActionResult<IEnumerable<Sample>>> Getsample()
        {
            return await _context.sample.ToListAsync();
        }

        // GET: api/Samples/5
        [HttpGet("{id}")]
        public async Task<ActionResult<Sample>> GetSample(long id)
        {
            var sample = await _context.sample.FindAsync(id);

            if (sample == null)
            {
                return NotFound();
            }

            return sample;
        }

        // PUT: api/Samples/5
        // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
        [HttpPut("{id}")]
        public async Task<IActionResult> PutSample(long id, Sample sample)
        {
            if (id != sample.Id)
            {
                return BadRequest();
            }

            _context.Entry(sample).State = EntityState.Modified;

            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!SampleExists(id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }

            return NoContent();
        }

        // POST: api/Samples
        // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
        [HttpPost]
        public async Task<ActionResult<Sample>> PostSample(Sample sample)
        {
            _context.sample.Add(sample);
            await _context.SaveChangesAsync();

            return CreatedAtAction("GetSample", new { id = sample.Id }, sample);
        }

        // DELETE: api/Samples/5
        [HttpDelete("{id}")]
        public async Task<IActionResult> DeleteSample(long id)
        {
            var sample = await _context.sample.FindAsync(id);
            if (sample == null)
            {
                return NotFound();
            }

            _context.sample.Remove(sample);
            await _context.SaveChangesAsync();

            return NoContent();
        }

        private bool SampleExists(long id)
        {
            return _context.sample.Any(e => e.Id == id);
        }
    }
}

実行してみます。

データが取得されていることが確認できます。