基本的なことはこちら→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 ICollection Tag { 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 ICollection Article { get; set; }
}
}
tagはユニークにしたいので Index(IsUnique=true)をつけています。
ユニーク制約をつけるためには、文字数が最大になっていたらつかないので文字数制限をつけます
プレーンなクラスとDBをつなぐクラス
model/BlogContext.cs
using System.Data.Entity;
namespace EntityFramework.model
{
class BlogContext : DbContext
{
public DbSet Articles { 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 件のコメント:
コメントを投稿