Windows上では、Visual Studioを使ってデザイナを使いながらMySQLからテーブル構造を引っ張ってこれるのだが、じゃあ、.NET Core の場合はどうするのか?
多分、マイグレーション機能を使って、MySql.Data.EntityFrameworkCore.Design あたりを NuGet でとってきてあれこれやるんだろうだが、面倒なので。
- あらかじめ、Windows の EF デザイナで取得したクラスを取ってくる。
- 手作業でテーブルクラスを作る
のどちらかがよい。
Redmine のプロジェクト(projects)とチケット(issues)は、こんな風になっている。これ自体は、Windows 上の .NET でも使えるし、Linux 上の .NET Core でも使える。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | public class projects { public int id { get ; set ; } public string name { get ; set ; } public string description { get ; set ; } public string homepage { get ; set ; } public int is_public { get ; set ; } public int ? parent_id { get ; set ; } public DateTime? created_on { get ; set ; } public DateTime? updated_on { get ; set ; } public string identifier { get ; set ; } public int status { get ; set ; } public int ? lft { get ; set ; } public int ? rgt { get ; set ; } public int inherit_members { get ; set ; } public int ? default_version_id { get ; set ; } } public class issues { public int id { get ; set ; } public int tracker_id { get ; set ; } public int project_id { get ; set ; } public string subject { get ; set ; } public string description { get ; set ; } public DateTime? due_date { get ; set ; } public int ? category_id { get ; set ; } public int status_id { get ; set ; } public int ? assigned_to_id { get ; set ; } public int priority_id { get ; set ; } public int ? fixed_version_id { get ; set ; } public int author_id { get ; set ; } public int lock_version { get ; set ; } public DateTime? created_on { get ; set ; } public DateTime? updated_on { get ; set ; } public DateTime? start_date { get ; set ; } public int done_ratio { get ; set ; } public double ? estimated_hours { get ; set ; } public int ? parent_id { get ; set ; } public int ? root_id { get ; set ; } public int ? lft { get ; set ; } public int ? rgt { get ; set ; } public int is_private { get ; set ; } public DateTime? closed_on { get ; set ; } } |
ちなみに、Visual Studio の EF デザイナだと、こんな projects クラスを吐き出す。アノテーションがついているので、asp.net mvc でスキャフォールディングするときに便利っぽい感じが…するが、まあなくても大丈夫
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | [Table( "redmine.projects" )] public partial class projects { public int id { get ; set ; } [Required] [StringLength(255)] public string name { get ; set ; } [Column(TypeName = "text" )] [StringLength(65535)] public string description { get ; set ; } [StringLength(255)] public string homepage { get ; set ; } public bool is_public { get ; set ; } public int ? parent_id { get ; set ; } public DateTime? created_on { get ; set ; } public DateTime? updated_on { get ; set ; } [StringLength(255)] public string identifier { get ; set ; } public int status { get ; set ; } public int ? lft { get ; set ; } public int ? rgt { get ; set ; } public bool inherit_members { get ; set ; } public int ? default_version_id { get ; set ; } } |
いわゆる、Entities なクラスはどうするかというと、NuGet で「MySql.Data.EntityFrameworkCore」を入れた後に、こんな風に手作業で作る。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public partial class RedmineEntities : DbContext { public RedmineEntities() { } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { base .OnConfiguring(optionsBuilder); optionsBuilder.UseMySQL( @"server=localhost;user id=redmine;password=redmine;database=redmine;port=3306;sslmode=None" ); } public DbSet<projects> projects { get ; set ; } public DbSet<issues> issues { get ; set ; } } |
Windows 上の DbContext と違うのは、データベースに接続するための設定が OnConfiguring メソッドをオーバライドして書くことになる。MySQL の場合は UseMySQL メソッドで指定する。この部分は拡張メソッドになっていて、インターフェースを決めるのではなくて、ダックタイピングなところが興味深いところ。以前は Factory だったような気もするのだが、こんな風にメソッド名でなんとなくルールを決めておくのが実に C# っぽい。
ここまで出来たら、後は .NET Core のコンソールアプリを作る。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class Program { static void Main( string [] args) { Console.WriteLine( "Hello MysQL EF " ); var ent = new RedmineEntities(); var items = ent.projects.ToList(); foreach ( var it in items) { Console.WriteLine($ "{it.id} {it.identifier} {it.name}" ); } } } |
シンプルに Redmine のプロジェクト一覧を表示しているだけなのだが、LINQ が使えるので SQL 文を書く必要がない。このぐらいの SELECT だと、普通に SQL 文を書いても手間は変わらないのだけど、Update とか Insert とかをやり始めると、ent.SaveChanges() で一発で書き込めるのは結構便利だったりする。特に、カラムの数が多い場合とか。
これを .net core の asp.net mvc で web api 化すると便利だったりするのだが、ターミナルを使ってコマンドラインで打てるのもよいだろう。GUI 絡みは .NET Core ではできないので、別途 Windows から MySQL のあるサーバーに繋げて、WPF で書くのがベターだろう。