💡

BlazorからMariaDBに接続する

2024/04/03に公開

概要

Qiitaより転記。
付随する知識は長くなるため。別記事にまとめる予定。
ここにはやり方とつまずき内容のみを記載しているつもり。わかりやすく書くって難しい…。

環境構築

VisualStudioをインストール

VisualStudioをインストールすればBlazorを始めることができる、
という記載を見かけたので素直にただインストールしたところ、
新規作成時にBlazorを選択することができずに詰んだ。
たまたま以下の記事[1]を見つけて、ワークロードでどれを選択すれば
Blzorを始められるかが記載してあったので、第一の難関を突破。

https://qiita.com/jsakamoto/items/4f3668e76eca6fca6b7b

DBをインストール

OracleやMySQL、A5M2が「何」かということすらわかっていなかった頃に比べれば、段違いの成長を感じる。[2]

せっかくなので、MySQLより性能が良いとされているMariaDBを選択した。[3]
名前もかわいいし、などという軽率な理由で知識もないまま選択したのが後の最大の詰み要因だったのだが、そんなことを知る由はない。

接続テスト用に「test」というテーブルを作り、主キーを「id」とした。
「id=1」のレコードを登録して、A5M2からSELECT文を流すと正常に取得可能な状態。

DBとアプリを繋ぐ何かをインストール(原因)

何度調べてもプロバイダーと呼ぶべきなのかエンジンと呼ぶべきなのかわからない。
VisualStudioが内部で何をしているかも未だによくわからないが、プログラムからDBに接続するとき、大抵「何か」が必要なことだけは何となく知っている。
それっぽい名前で調べると、CDataという有料のパッケージばかり出てきて困った。

EntityFrameworkと検索すると、無限にあるのか?と思われる結果の中から、
本当に必要なものを調べてインストールする、という作業は難易度がとても高い。
当時のnugetパッケージのインストール状態が以下の通り。

past_nuget.png

この状態で後述のコードを動かしてもDB接続エラーにはならず、
ただデータが存在しない例外が発生するだけだったので、
インストールするプロバイダーは間違っていないと思い込んでいた。
二か月後、調査しなおして、DBからデータを取得できるようになった状態が以下。

image.png

つまり調べ方が悪くてインストールするDBプロバイダーが間違っていただけだった。
インストールしたDBによってどれを使用すれば良いかの参考資料は以下の通り公式ドキュメントに記載がある。

https://learn.microsoft.com/ja-jp/ef/core/providers/?tabs=dotnet-core-cli

MySQLだけではなくMariaDBにも対応しているPomelo...をインストールして、
サンプルコードからUseMySQLメソッドの使い方を確認して実装することによって、
データを取得できるようになった。めでたしめでたし。

コードを書く

以下、参考にさせて頂いた記事。あとは公式ドキュメントを読んでなんとかした。

https://qiita.com/nakamurau1@github/items/eae0458039a09e6f0c34

コードの内容や、どうしてこのコードに至ったのかは別記事に記載予定。
以下、主旨に直接関係しないコードは全て省略。変数名称も気にしないでほしい。

・プロジェクト作成時に作られるファイルへ追記

var serverVersion = new MySqlServerVersion(new Version(11, 3, 0));}
// 以下は「var app = builder.Build();」行より後に追記するとエラーになる
builder.Services.AddDbContextFactory<MyContext>
    (opt => opt.UseMySql("server=localhost;database=mysql;userid=xxx;password=xxx;database=mysql",serverVersion));
builder.Services.AddScoped<DbConnectionService>();
@inject DbConnectionService ser;
<p role="status">test count: @testint</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
    private int testint = 0;
    private void IncrementCount()
    {
        var noNum = ser.GetTest();
        testint = noNum is null ? 999 : noNum.Id;
    }
}

・ファイル新規作成

public class TestTable {
    // プロパティ名称はDBのテーブル項目名に合わせているが、大文字小文字の違いは関係なし
    public int id { get; set; }
    public string name { get; set; } = string.Empty;
}
public class MyContext : DbContext {
    public MyContext(DbContextOptions<MyContext> opt) : base(opt) { }
    // こちらのプロパティ名もテーブル名称に合わせた。同じく大文字小文字関係なし
    public DbSet<TestTable> Test { get; set; }
}
    public class DbConnectionService
    {
        private IDbContextFactory<MyContext> _conFac;
        public DbConnectionService(IDbContextFactory<MyContext> factory)
        {
            _conFac = factory;
        }
        public TestTable? GetTest()
        {
            using var con = _conFac.CreateDbContext();
            var t = con.Test.AsNoTracking();
            return con.Find<TestTable>(1);
        } 
    }

おしまい

ひとまず自宅環境でアプリからDBに接続するという最大難関を突破できたので、
これで何でも作れるね。(なんでもつくれるとは言ってない)
HTMLがあまり得意ではないので、その点はどうしてフォームと同じように作れないんだと辛い点ではあるが、なんとか頑張っていきたい。
脱初心者に向けて…。

脚注
  1. メモ
    ・Othertoolsetsの「.NetCore・・・」はなかったのでインストールしていない。
    ・BlazorServerを選択して開始。この選択に特に意味はない。 ↩︎

  2. 自分のPCにDBをDLするつもりでA5M2を入れたことがある。A5M2はSQLを打てば答えが返ってくるツールという認識しかなかったのだと思われる。 ↩︎

  3. MySQLの方がメジャーだろうしググればいろいろ出てくるだろうとは思ったのだが、そうは言ってもやり方は大きくMySQLと変わらないだろうし、勉強になるかと思って…。
    実際勉強にはなったので、今となっては良かったのかもしれない。 ↩︎

Discussion