1. きっかけ
MacOS で文献管理システムを作ろうと奮闘しているとき、スキャフォールドの仕方が分からず色々調べながらやってました。できたにはできたのですが、思ってたのと違ったので失敗談として記録。
2. 環境
- MacOS Mojave 10.14.1
- .Net Core 2.1.400
3. 文献管理用データベースモデルの作成
コードはこんな感じです。Models > Book.cs
public class Book { public int Id { get; set; } //データベースのキーID public string タイトル { get; set; } //文献タイトル public string 著者 { get; set; } //文献の著者 public string 出版社 { get; set; } //文献の出版社 [DataType(DataType.Date)] public DateTime 発行日 { get; set; } //文献の発行日 public string 分野 { get; set; } //文献の分類 public string リンク { get; set; } //文献のリンク先 }
データベースコンテキストは Model > RazorPagesBooksContext.cs で作成。
public class RazorPagesBooksContext : DbContext { public RazorPagesBooksContext(DbContextOptions<RazorPagesBooksContext> options) : base(options) { } public DbSet<BooksDatabase.Models.Book> Book { get; set; } }
MySQL データベース用に接続文字列を指定。(appsettings.json)
{ "ConnectionStrings": { "DefaultConnection": "Server=localhost;User Id=root;Password=pass;Database=ApplicationDbContext", "BooksDbContext": "Server=localhost;User Id=root;Password=pass;Database=BooksDbContext" }, //略
NuGet にてパッケージを追加
- Microsoft.VisualStudio.Web.CodeGeneration.Design
- Microsoft.EntityFrameworkCore.Design
- Pomelo.EntityFrameworkCore.MySql
Startup.cs の UseSqlServer メソッドを UseMysql メソッドに変更
//略 public void ConfigureServices(IServiceCollection services) { services.Configure<CookiePolicyOptions>(options => { // This lambda determines whether user consent for non-essential cookies is needed for a given request. options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; }); services.AddDbContext<ApplicationDbContext>(options => options.UseMySql( Configuration.GetConnectionString("DefaultConnection"))); services.AddDefaultIdentity<IdentityUser>() .AddEntityFrameworkStores<ApplicationDbContext>(); services.AddDbContext<RazorPagesBooksContext>(options => options.UseMySql(Configuration.GetConnectionString("BooksDbContext"))); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); //略
4. スキャフォールディング
この時点で3回ほどやり直していています。Model のデータベース要素 (Books.cs) をもとにして、View にて Pages/Books を作ろうとすると、なぜか "Books" が競合してしまうようでビルドできませんでした。なので Book.cs として作成し、Pages/Books に View を作るようにします。その前にリストアとビルドをする必要があります。
sudo dotnet aspnet-codegenerator razorpage -m book -dc RazorPagesBooksContext -udl -outDir Pages/Books --referenceScriptLibraries
これで VIew が生成されます。
5. データベースの移行と更新
先にビルドしてスキャフォールドされたデータを適用します。データベースを移行し、更新します。
sudo dotnet ef migrations add --context RazorPagesBooksContext BooksDbContext
ここで一旦ビルド。そして更新します。
sudo dotnet ef database update --context RazorPagesBooksContext
問題なく生成されました。
6. 実行結果
データベースが動いているか実行して確認してみます。まだリンクを作成していないので、直接 URL からアクセスします。 localhost:port/Books
ファーッ! 思ってたの違うぅ
何が違うかというと、
- なぜかデザインが適用されていない
- Create New ボタンが押せず、ただのテキストになっている
- なんかダサい
- なんかダサい
- なんかダサい
とかです。もうこの時点で嫌な気がするんですが、念のため直接 URL を指定して文献作成ページに飛びます。
(゚∀゚)アヒャ(゚∀゚)アヒャ(゚∀゚)アヒャ
もうだめです。なぜか "Create" だけボタンとして押せるのですが、押してみると空白のページに飛びます。これじゃどこに何を入力していいかさっぱりですね。
7. 考察
スキャフォールドするときに View しか生成されていないことに気が付きました。Model をもとに View を作成されているんですが、肝心の Controller が生成されていません。なのでボタンをクリックしても処理されないのですね。しかし、View が分かりません。なぜこんなしょぼいページになっているのか...。これは自分で修正するしかないのか、それともスキャフォールドで修正できるのか...。これはやってみないと分かりませんね。
8. 結論
スキャフォールディングする方法が分かっただけでもかなりの収穫なのですが、それにしても悔しいです。
近いうちにリベンジします。