「せばな」は言わない

綱の上を歩き、岩を登るエンジニア

【ASP.net Core】ASP.net core Apiで既存のDBに接続する

ASP.net core Apiで既存のDBに接続する

前回はASP.net core APIのプロジェクト作成まで実施した。
今回はその続きをやっていく。

だいたいどの記事も新規に作成したDBについてばかりで既存のDBに接続する内容が書いてないので、ネットから断片的に集めた情報をつなぎ合わせて構築していった。
つらかった。

下の記事は既存のDBからスキャフォルディングする方法が書いてあり本当に助かった。ありがとうございます!
DBContextの作成まではこの記事通りでOK。

  • SQLServerからのスキャフォルディング

mseeeen.msen.jp

ツールとパッケージのインストール

Entity Framework Core ツール
dotnet tool install --global dotnet-ef
パッケージインストール
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Microsoft.EntityFrameworkCore.SqlServer

DBをスキャフォルドする

dotnet ef dbcontext scaffold "接続文字列" Microsoft.EntityFrameworkCore.SqlServer --table テーブル名 --context-dir DBコンテキストのディレクトリ --output-dir モデルクラスのディレクトリ --context DBコンテキストのクラス名

ファイルを更新(上書き)したい場合は末尾に"--force"を付加する。

しっかし毎回この接続文字列をこしらえるのがダルいな…。テーブル名選んで接続文字列を吐き出すツールでも作ろうかなぁ。

作成が完了すると、自分の環境では作成されたファイルにエラーがある旨が表示。
どうやら以下の記述らしい。

#nullable disable

エラー内容は

機能 'Null 許容参照型' は C# 7.3 では使用できません。8.0 以上の言語バージョンをお使いください。

とのこと。

C#8.0を使用する方法は以下の記事に書いてある。
http://blog.shos.info/archives/2019/09/201909netcsharp.html

プロジェクト ファイル (*.csproj など) に以下2点追記。

  • 8.0
  • enable
  <?xml version="1.0" encoding="utf-8"?>
  <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      ...
      <PropertyGroup>
        ...
        <LangVersion>8.0</LangVersion>
        <Nullable>enable</Nullable>
        ...

これで正常な状態となったが、大変なのはここからだった。
ASP.NET CoreはDIパターンというものを採用しており、それを勉強するのに時間を使ってしまった。
なお、まだ理解はしていない模様。

インターフェース

次にデータ取得ロジックを各リポジトリクラスに実装するためのインターフェースを適当に準備。

using System.Collections.Generic;
using AspApiTest.Models;

namespace AspApiTest.Interfaces
{ 
    public interface IApiTestUser
    {
        IEnumerable<USER> GetUser();
    }
}
リポジトリ

先に作成したインターフェースを実装したリポジトリクラスを作成

using System.Linq;
using System.Collections.Generic;
using AspApiTest.Interfaces;
using AspApiTest.DbContext;
using AspApiTest.Models;

namespace AspApiTest.Repositories
{
    public class UserRepository : IApiTestUser
    {
        private Context _dbcontext;

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="context"></param>
        public UserRepository(Context context) {
            _dbcontext = context;
        }
        public IEnumerable<USER> GetUsers() {
            using(_dbcontext) {
                // ここにDBからの取得ロジックを記入
                return _dbcontext.USERs.Where(n => n.NAME.Contains("佐藤")).ToList();
                
            }
        }
    }
}

コントローラー

ユーザーコントローラーを作成。

using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using AspApiTest.Interfaces;
using AspApiTest.Models;
namespace AspApiTest.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class ApiUserController : ControllerBase
    {
        private readonly IApiTestUser _apiTestUser;
        
        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="apiTestUser"></param>
        public ApiUserController(IApiTestUser apiTestUser) {
            _apiTestUser = apiTestUser;
        }

        [HttpGet]
        /// <summary>
        /// ユーザを取得
        /// </summary>
        /// <returns></returns>
        public IEnumerable<USER> GetUsers()
        {
            // インターフェースを介してリポジトリのクラスからユーザを取得する
            var result = _apiTestUser.GetUsers();
            return result;
        }
    }
}
オブジェクトを注入する

コントローラで使用するオブジェクトはStartup.csというファイルに明記しなければいけないらしい。

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<Context>(opt => opt.UseSqlServer(Configuration.GetConnectionString("Database")));
            services.AddTransient<IApiTestUser, UserRepository>();
            services.AddControllers();
        }

ここで、以下の一文はDBの接続文字列を指定している。
接続文字列自体は「appsettings.json」に記載している。

 services.AddDbContext<Context>(opt => opt.UseSqlServer(Configuration.GetConnectionString("Database")));

appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "Database": ここにDBの接続文字列!!
  }
}


これですべての準備が整った。
あとはVSCodeでデバッグをするとブラウザが起動する。
※しないこともあるので、その場合は"https://localhost:5001"にアクセス。

アドレスの後ろにコントローラー名をつけてやると作成したコントローラー内のメソッドに入っていく。
ブレークポイントを張って見るのがいいと思う。

自分の場合はコントローラー名が"ApiUserController"なので以下のアドレスになる。
https://localhost:5001/ApiUser

DBから取得したデータが返ってくれば成功。

長くなったがこれでASP.net CoreでのAPI開発の足がかりを掴むことができた。