.NET Core CLI の View / Controller の scaffold 機能を試す
Ruby on Rails で長らくアプリケーション開発をしてきたものとしては、Rails の Scaffold 機能はその利用頻度は場合によるものの、とても好きな機能でした。
もちろん自動生成コードは完璧ではないものの、コマンド 1 撃でまずは CRUD が動かせるというのは、まさに土台として嬉しい体験だったんです。
ASP.NET Core でも同じことはできるだろうか?
目標は Rails の rails generate scaffold User name:string email:string
で Model / View / Controller / Migration の全てが生成される感じです。
結論は、できません でした。
でも、ある程度のところはできた、というか C# で書くならこれぐらいがちょうどいいかという感じでした。どうちょうどいいかは後述。
aspnet-codegenerator
dotnet aspnet-codegenerator command | Microsoft Docs
これが、今回の話の中心であり、もはや上記のリンク見てもらえれば終わりです 😅
今回見る機能は公式のチュートリアルにも Mac や VS Code を使うサンプルで登場します(つまり Windows の Visual Studio を使わないケース)
Add a model to an ASP.NET Core MVC app | Microsoft Docs
はい、チュートリアルも見てもらえればもう書くことないです。
一応やってみる
モデルは自分で書く
チュートリアルの通り Movie
class と MovieContext
class を書きます。そう、Model 部分は手書きする必要があります。
ただ、チュートリアルでは Model も同じ project に入れていますが、Console app 等からも同じデータアクセスの仕組みを使いたい場合も多いと思うので、多くのケースでは project を分けるのではと思います。
そうなると、Rails の (full) scaffold のように Model や Migration も同じ project に作られてしまうよりは、Controller / View だけ Scaffold するのがちょうどいいように思います。
というか、私も Rails では Model はたいてい手書きしてた。
たくさん package が必要
ここで出てくるのが次ですね。
dotnet tool install --global dotnet-ef dotnet add package Microsoft.EntityFrameworkCore.SQLite dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design dotnet add package Microsoft.EntityFrameworkCore.Design dotnet add package Microsoft.EntityFrameworkCore.SqlServer
まじか、と思うのは SQLite
を利用する前提なのに、 SqlServer
の package も必要になることです。
これ、deploy 時にも省けないのだとしたら deploy の size に影響するし、single binary にするんであれば、そのまま膨れ上がらないかなと 🙄
別プロジェクトを作って上記を import し、そこから MVC project に向けて Scaffold というのも試してみたんですが、やはり MVC project にこの package 参照が無いと実行できませんでした。。うーん、やり方悪いのかなぁ。
コネクションの設定
Startup
と appsettings.json
にコネクションの設定を。
ここに書いておくだけで、後で出てくる dotnet-ef
コマンドも実行先の接続先をここから読んでくれるようです。なるほどなぁ。
ちなみに、MVC project で dotnet-ef
を実行しない場合には、接続先設定を desing-time factory というので別途定義できます。Model 部分だけ別プロジェクトにするなら使えそう。
Design-time DbContext Creation - EF Core | Microsoft Docs
Scaffold 実行
dotnet aspnet-codegenerator controller -name MoviesController -m Movie -dc MvcMovieContext --relativeFolderPath Controllers --useDefaultLayout --referenceScriptLibraries
どういう Controller 名にするかとかは自動で設定する訳ではありません。デフォルトは自動にしてくれもいいような気もしますが、まあ Model と Controller を同じ名前にしてしまおうというのは、実際最初だけなんでこれでいい気がします。
この実行が終わると View / Controller が生成されます 🎉🎉🎉
後は DB を migration すれば起動できる
おなじみのこれですね。
dotnet ef migrations add InitialCreate dotnet ef database update
やってみて
もっと手間取るかと思いましたが、さくっとできました。
最初はチュートリアルを探せてなかったので、自分でオプション試しながらやってましたが、最初からチュートリアル見てたら読んで終わりにしてたかも 😎
Win の Visual Studio だと、GUI でその辺もやってくれるんでしょうけど、コマンド勢でも同じようにできて嬉しいですね。
チュートリアルのコードの方がいいと思いますが、私が今回書いたコードも以下に置いてあります。
https://github.com/dany1468/dotnet_ScaffoldExample/tree/master
dotnet tools は local に入れてある。
Appendix: Rails console も欲しい人生だった
Rails で最高の体験の一つは Rails console だったわけですが、それを ASP.NET Core でもやろうとしてみました。が、現状は失敗しました。
どうしても TypeInitializationException
が出てしまい dotnet-script
からは EF Core の呼び出しができなかった。
SQLite / SQLServer、Wiin/Mac と複数環境で試してみたんですが駄目だったのですが、以下のテストケース見てると、ある時点では通っていたようなので、自分が悪いか、現時点だけかなぁという気がしています。
https://github.com/filipw/dotnet-script/blob/master/src/Dotnet.Script.Tests/TestFixtures/NativeLibrary/NativeLibrary.csx
この辺は、また調査する時間ができたら切り分けてみようかなと思います。
ただ、Rails console like なことができたとして、誰得なのかというのはある。割とさくっと console app 書いて試すとかが多いのかなぁと。けど、REPL が欲しい。。