基本的なことはこちら→ConsoleApplicationでCodeFirst
多対多です。
ブログの記事にタグがぶら下がる状態がまさにそれですね。
イメージしやすいのでこれを題材にいろいろ掘り下げてみます。
記事のテーブル。
名前と本文だけのシンプルな構成
model/Article.cs
using System.Collections.Generic; namespace EntityFramework.model { class Article { public int ID { get; set; } public string Title { get; set; } public string Body { get; set; } //リレーション(相手側が多なのでCollection) public virtual ICollectionTag { get; set; } } }
タグのテーブル
model/Tag.cs
using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace EntityFramework.model { class Tag { public int ID { get; set; } [Required] [Index(IsUnique=true)] [MaxLength(50)] public string Name { get; set; } //リレーション(相手側が多なのでCollection) public virtual ICollectionArticle { get; set; } } }
tagはユニークにしたいので Index(IsUnique=true)をつけています。
ユニーク制約をつけるためには、文字数が最大になっていたらつかないので文字数制限をつけます
プレーンなクラスとDBをつなぐクラス
model/BlogContext.cs
using System.Data.Entity; namespace EntityFramework.model { class BlogContext : DbContext { public DbSetArticles { get; set; } public DbSet Tags { get; set; } } }
Add-Migrationして Update-Databaseしてテーブルを作成します。
※こまかいとこはすっとばします。
多対多なので自動的に中間テーブル(TagArticles)が作られています。
データを格納してみます。
Program.cs
using EntityFramework.model; using System.Collections.Generic; namespace EntityFramework { class Program { static void Main(string[] args) { BlogContext db = new BlogContext(); // Article側にTagをぶら下げる Article article = new Article { Body = "Body_A", Title = "Title_A" }; Tag tag1 = new Tag { Name = "C#" }; Tag tag2 = new Tag { Name = "SQL Server" }; article.Tag = new List{ tag1, tag2 }; db.Articles.Add(articleA); db.SaveChanges(); // 登録 } } }
記事Aに C#とSQL Serverを登録しています。
タグはUniqueキー制約をつけているのでこんな登録の仕方したらだめなわけですが
サンプルということもあって、初回登録で空なのでこんな書き方しています。
記事Bを追加します。
今回は、タグがすでにあることを想定して事前に取得して、なければタグのインスタンスを生成するようにしています。
??演算子で nullだったら後ろの処理をするようにしています。
Program.cs
using EntityFramework.model; using System.Collections.Generic; using System.Linq; namespace EntityFramework { class Program { static void Main(string[] args) { BlogContext db = new BlogContext(); // Article側にTagをぶら下げる Article article = new Article { Body = "Body_B", Title = "Title_B" }; Tag tag1 = db.Tags.Where(t => t.Name == "C#").FirstOrDefault(); tag1 = tag1 ?? new Tag { Name = "C#" }; Tag tag2 = db.Tags.Where(t => t.Name == "SQL Server").FirstOrDefault(); tag2 = tag2 ?? new Tag { Name = "SQL Server" }; Tag tag3 = db.Tags.Where(t => t.Name == "ASP.NET").FirstOrDefault(); tag3 = tag3 ?? new Tag { Name = "ASP.NET" }; article.Tag = new List{ tag1, tag2, tag3 }; db.Articles.Add(article); db.SaveChanges(); // 登録 } } }
Program.cs
using EntityFramework.model; using System.Collections.Generic; using System.Linq; namespace EntityFramework { class Program { static void Main(string[] args) { BlogContext db = new BlogContext(); // Article側にTagをぶら下げる Article article = new Article { Body = "Body_C", Title = "Title_C" }; Tag tag1 = db.Tags.Where(t => t.Name == "C#").FirstOrDefault(); tag1 = tag1 ?? new Tag { Name = "C#" }; Tag tag2 = db.Tags.Where(t => t.Name == "ASP.NET").FirstOrDefault(); tag2 = tag2 ?? new Tag { Name = "ASP.NET" }; article.Tag = new List{ tag1, tag2 }; db.Articles.Add(article); db.SaveChanges(); // 登録 } } }
0 件のコメント:
コメントを投稿