【失敗】.NET6 Blazor Server の SQL Server Express(EF Core)で読み書きする


【環境】

Windows 11
Visual Studio 2022 Ver 17.1.1

エンティティクラスの作成

  • Visual Studio 2022 で 「Blazor Server アプリ」 プロジェクトを作成する。(BlazorApp1、.NET6、認証:個別アカウント、HTTPS有効)
  • エンティティクラス Data/T_Member.cs を作成
Data/T_Member.cs
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace BlazorApp1.Data
{
    public class T_Member
    {
        [Column(TypeName = "int"), Key, Required]
        public int Id { get; set; }
        [Column(TypeName = "nvarchar(5)"), Required]
        public string FamilyName { get; set; }
        [Column(TypeName = "nvarchar(5)")]
        public string FirstName { get; set; }
        [Column(TypeName = "date")]
        public DateTime Birthday { get; set; }
        [Column(TypeName = "datetime"), Required]
        public DateTime CreateTime { get; set; }
    }
}

コンテキストクラス Data/ApplicationDbContext.cs に追加

Data/ApplicationDbContext.cs
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;

namespace BlazorApp1.Data
{
	public class ApplicationDbContext : IdentityDbContext
	{
		public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
			: base(options)
		{
		}

		// エンティティクラス T_Member を登録
		public DbSet<T_Member> T_Members { get; set; }

		// デモデータ作成
		protected override void OnModelCreating(ModelBuilder modelBuilder)
		{
            base.OnModelCreating(modelBuilder);

			modelBuilder.Entity<T_Member>().HasData(
				new T_Member { Id = 1, FamilyName = "田中", FirstName = "一郎", Birthday = DateTime.Parse("2000/01/01"), CreateTime = DateTime.Now },
				new T_Member { Id = 2, FamilyName = "二中", FirstName = "二郎", Birthday = DateTime.Parse("2000/01/02"), CreateTime = DateTime.Now },
				new T_Member { Id = 3, FamilyName = "三中", FirstName = "三郎", Birthday = DateTime.Parse("2000/01/03"), CreateTime = DateTime.Now }
			);
		}
	}
}

データーベース作成

  • Data/Migrations フォルダを削除する。
  • Dos窓でプロジェクトBlazorApp1ディレクトリに移動して、新しくマイグレーション・ソースを作成してDBへテーブルを作成する。
    ※ ソースコードの保存を忘れずに
> dotnet tool install --global dotnet-ef  // dotnet ef コマンドインストール
> dotnet ef migrations add Initial         // Migrationsフォルダにマイグレーション・ソース作成
> dotnet ef database update                // マイグレーション・ソースを基にDBにテーブルおよび初期データ作成
// > dotnet ef migrations add Seeding      // 使わなかった

Visual Studio 2022 の SQL Server オブジェクトエクスプローラー でテーブル dbo.T_Members が作成されているのでデータ表示して初期データが作成されているか確認する。

テーブルT_Membersへのアクセス用APIの作成

  • Controllersフォルダを作成して、右クリック・メニューで「新規スキャフォールディングアイテム」をクリックする。

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

    エラーが出るが再度上記の追加を実行するとするとなぜかControllersフォルダに正常にAPIが作成される。

API確認

プロジェクトをデバッグ起動してURLをhttps://localhost:xxxx/api/T_MemberにアクセスするとJsonでデータが表示される。

[{"id":1,"familyName":"田中","firstName":"一郎","birthday":"2000-01-01T00:00:00","createTime":"2022-03-29T10:30:05.04"},{"id":2,"familyName":"二中","firstName":"二郎","birthday":"2000-01-02T00:00:00","createTime":"2022-03-29T10:30:05.04"},{"id":3,"familyName":"三中","firstName":"三郎","birthday":"2000-01-03T00:00:00","createTime":"2022-03-29T10:30:05.04"}]
  • 会員リストのページPages/Members.razorを作成する。
Pages/Members.razor.html
@page "/members"
@using BlazorApp1.Data
@inject HttpClient Http

<h1>会員リスト</h1>

<p>DBテーブル "T_Members" から API を通して取得した Json をこのページで HTML化して表示した。</p>

@if (members == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <table class="table">
        <thead>
            <tr>
                <th>ID</th>
                <th></th>
                <th></th>
                <th>生年月日</th>
                <th>作成日時</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var member in members)
            {
                <tr>
                    <td>@member.Id.ToString()</td>
                    <td>@member.FamilyName</td>
                    <td>@member.FirstName</td>
                    <td>@member.Birthday.ToString("yyyy年 MM月 dd日")</td>
                    <td>@member.CreateTime.ToString("yyyy/MM/dd HH:mm:ss.fff")</td>
                </tr>
            }
        </tbody>
    </table>
}

@code {
    private List<T_Member>? members;

    protected override async Task OnInitializedAsync()
    {
        members = await Http.GetFromJsonAsync<List<T_Member>>("api/T_member");
    }
}
  • NavMenu.razorを編集して左サイドメニューに追加する。
Shared/NavMenu.razor.html
        :
        <div class="nav-item px-3">
            <NavLink class="nav-link" href="fetchdata">
                <span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
            </NavLink>
        </div>
        27行目:この下に下記コードを挿入
        <div class="nav-item px-3">
            <NavLink class="nav-link" href="members">
                <span class="oi oi-people" aria-hidden="true"></span> 会員リスト
            </NavLink>
        </div>
        :

プロジェクトをデバッグ起動して会員リストをクリックする。

結果 エラー!

Blazor Server では HttpClient を注入できないらしい
Server-side Blazor does not provide HttpClient for injection

解決策としてはWebApi+SignalRの連携が一番汎用性があるようだ。

WebApi+SignalRにつづく・・・かも・・・

引用