このビデオと詳細なチュートリアルでは、新しいデータベースを対象とする Code First 開発の概要について説明します。 このシナリオには、存在しないデータベースと Code First によって作成されるデータベース、または Code First が新しいテーブルを追加する空のデータベースをターゲットにすることが含まれます。 Code First では、C# クラスまたは VB.Net クラスを使用してモデルを定義できます。 必要に応じて、クラスとプロパティの属性を使用するか、fluent API を使用して、追加の構成を実行できます。
ビデオを見る
このビデオでは、新しいデータベースをターゲットとする Code First 開発の概要について説明します。 このシナリオには、存在しないデータベースと Code First によって作成されるデータベース、または Code First が新しいテーブルを追加する空のデータベースをターゲットにすることが含まれます。 Code First では、C# クラスまたは VB.Net クラスを使用してモデルを定義できます。 必要に応じて、クラスとプロパティの属性を使用するか、fluent API を使用して、追加の構成を実行できます。
発表者: ローワン・ミラー
前提条件
このチュートリアルを完了するには、少なくとも Visual Studio 2010 または Visual Studio 2012 をインストールする必要があります。
Visual Studio 2010 を使用している場合は、 NuGet もインストールする必要があります。
1. アプリケーションを作成する
簡単にするために、Code First を使用してデータ アクセスを実行する基本的なコンソール アプリケーションを構築します。
- Visual Studio を開く
- ファイル -> 新規 -> プロジェクト...
- 左側のメニューとコンソール アプリケーションから Windows を選択する
- 名前として 「CodeFirstNewDatabaseSample 」と入力します
- [OK] を選択します。
2. モデルを作成する
クラスを使用して非常に単純なモデルを定義しましょう。 Program.cs ファイルで定義するだけですが、実際のアプリケーションでは、クラスを別々のファイルに分割し、別のプロジェクトにする可能性があります。
Program.csの Program クラス定義の下に、次の 2 つのクラスを追加します。
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public virtual List<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public virtual Blog Blog { get; set; }
}
2 つのナビゲーション プロパティ (Blog.Posts と Post.Blog) を仮想にしていることがわかります。 これにより、Entity Framework の遅延読み込み機能が有効になります。 遅延読み込みとは、これらのプロパティにアクセスしようとすると、これらのプロパティの内容がデータベースから自動的に読み込まれることを意味します。
3. コンテキストを作成する
次に、データベースとのセッションを表す派生コンテキストを定義し、データのクエリと保存を行います。 System.Data.Entity.DbContext から派生し、モデル内の各クラスに対して型指定された DbSet<TEntity> を公開するコンテキストを定義します。
Entity Framework の型の使用を開始したので、EntityFramework NuGet パッケージを追加する必要があります。
- Project –> NuGet パッケージの管理... 注: NuGet パッケージの管理... オプションがない場合は、最新バージョンの NuGet をインストールする必要があります
- [ オンライン ] タブを選択する
- EntityFramework パッケージを選択する
- [インストール]をクリックします。
Program.csの先頭に System.Data.Entity の using ステートメントを追加します。
using System.Data.Entity;
Program.csの Post クラスの下に、次の派生コンテキストを追加します。
public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
}
Program.csに含める必要がある内容の完全な一覧を次に示します。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;
namespace CodeFirstNewDatabaseSample
{
class Program
{
static void Main(string[] args)
{
}
}
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public virtual List<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public virtual Blog Blog { get; set; }
}
public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
}
}
これは、データの格納と取得を開始するために必要なすべてのコードです。 明らかに、背後ではかなりのことが起こっています、そして、我々はすぐにそれを見てみましょうが、最初にそれを実際に見てみましょう。
4. データの読み取りと書き込み
次に示すように、Program.csで Main メソッドを実装します。 このコードは、コンテキストの新しいインスタンスを作成し、それを使用して新しいブログを挿入します。 次に、LINQ クエリを使用して、タイトルごとにアルファベット順に並べられたデータベースからすべてのブログを取得します。
class Program
{
static void Main(string[] args)
{
using (var db = new BloggingContext())
{
// Create and save a new Blog
Console.Write("Enter a name for a new Blog: ");
var name = Console.ReadLine();
var blog = new Blog { Name = name };
db.Blogs.Add(blog);
db.SaveChanges();
// Display all Blogs from the database
var query = from b in db.Blogs
orderby b.Name
select b;
Console.WriteLine("All blogs in the database:");
foreach (var item in query)
{
Console.WriteLine(item.Name);
}
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
}
これで、アプリケーションを実行してテストできます。
Enter a name for a new Blog: ADO.NET Blog
All blogs in the database:
ADO.NET Blog
Press any key to exit...
マイ データはどこにありますか?
慣例により、DbContext はデータベースを自動的に作成しました。
- ローカル SQL Express インスタンスが使用可能な場合 (Visual Studio 2010 で既定でインストールされます)、Code First によってそのインスタンスにデータベースが作成されます
- SQL Express を使用できない場合、Code First は LocalDB を試して使用します (Visual Studio 2012 では既定でインストールされます)
- データベースの名前は、派生コンテキストの完全修飾名 (この場合は CodeFirstNewDatabaseSample.BloggingContext) の後に付けられます。
これらは既定の規則に過ぎず、Code First で使用されるデータベースを変更するさまざまな方法があります。詳細については、「 DbContext がモデルとデータベース接続を検出する方法 」トピックを参照してください。 このデータベースには、Visual Studio のサーバー エクスプローラーを使用して接続できます。
サーバー エクスプローラーの表示 ->
[データ接続] を右クリックし、[接続の追加]を選択します。..
以前にサーバー エクスプローラーからデータベースに接続していない場合、データ ソースとして Microsoft SQL Server を選択する必要があります。
インストールした LocalDB または SQL Express のいずれかに接続する
Code First によって作成されたスキーマを調べることができるようになりました。
DbContext は、定義した DbSet プロパティを調べることで、モデルに含めるクラスを特定しました。 次に、コード優先規則の既定のセットを使用して、テーブル名と列名の決定、データ型の決定、主キーの検索などを行います。 このチュートリアルの後半では、これらの規則をオーバーライドする方法について説明します。
5. モデルの変更に対処する
次に、モデルにいくつかの変更を加えます。これらの変更を行うときは、データベース スキーマも更新する必要があります。 これを行うには、Code First Migrations と呼ばれる機能、または短く「移行」を使用します。
移行により、データベース スキーマをアップグレード (およびダウングレード) する方法を説明する一連の手順を順序付けすることができます。 移行と呼ばれるこれらの各手順には、適用する変更を記述するコードが含まれています。
最初の手順は、BloggingContext の Code First Migrations を有効にすることです。
ツール -> ライブラリ パッケージ マネージャー -> パッケージ マネージャー コンソール
パッケージ マネージャー コンソール で Enable-Migrations コマンドを実行する
次の 2 つの項目を含む新しい Migrations フォルダーがプロジェクトに追加されました。
- Configuration.cs – このファイルには、移行が BloggingContext の移行に使用する設定が含まれています。 このチュートリアルでは何も変更する必要はありませんが、ここではシード データの指定、他のデータベースのプロバイダーの登録、移行が生成される名前空間の変更などを行うことができます。
- <timestamp>_InitialCreate.cs – これは、データベースに既に適用されている変更を表し、空のデータベースからブログと投稿テーブルを含むデータベースに移行します。 Code First ではこれらのテーブルを自動的に作成しましたが、マイグレーションにオプトインしたため、それらはマイグレーションとして変換されました。 Code First は、この移行が既に適用されていることをローカル データベースにも記録しています。 ファイル名のタイムスタンプは、順序付けのために使用されます。
次に、モデルに変更を加え、ブログ クラスに Url プロパティを追加します。
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public virtual List<Post> Posts { get; set; }
}
- パッケージ マネージャー コンソールで Add-Migration AddUrl コマンドを実行します。 Add-Migration コマンドは、前回の移行以降の変更を確認し、検出された変更を含む新しい移行をスキャフォールディングします。 移行に名前を付けることができます。この場合、移行 'AddUrl' を呼び出します。 スキャフォールディングされたコードは、文字列データを保持できる URL 列を dbo.Blogs の表に追加する必要があることを示しています。 必要に応じて、スキャフォールディングされたコードを編集できますが、この場合は必要ありません。
namespace CodeFirstNewDatabaseSample.Migrations
{
using System;
using System.Data.Entity.Migrations;
public partial class AddUrl : DbMigration
{
public override void Up()
{
AddColumn("dbo.Blogs", "Url", c => c.String());
}
public override void Down()
{
DropColumn("dbo.Blogs", "Url");
}
}
}
- パッケージ マネージャー コンソールで Update-Database コマンドを実行します。 このコマンドは、保留中の移行をデータベースに適用します。 InitialCreate の移行は既に適用されているため、移行では新しい AddUrl 移行が適用されます。 ヒント: Update-Database を呼び出すときに –Verbose スイッチを使用して、データベースに対して実行されている SQL を確認できます。
これで、新しい URL 列がデータベースの Blogs テーブルに追加されました。
6. データ注釈
ここまでは、EF が既定の規則を使用してモデルを検出できるようにしますが、クラスが規則に従わない場合があり、さらに構成を実行できる必要があります。 これには 2 つのオプションがあります。このセクションのデータ注釈と、次のセクションの fluent API について説明します。
- モデルに User クラスを追加しましょう
public class User
{
public string Username { get; set; }
public string DisplayName { get; set; }
}
- また、派生コンテキストにセットを追加する必要があります
public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
public DbSet<User> Users { get; set; }
}
- 移行を追加しようとすると、"EntityType 'User' にはキーが定義されていません。この EntityType のキーを定義します。"というエラーが表示されます。なぜなら、EFにはユーザー名がUserの主キーであることを認識する手段がないからです。
- ここではデータ注釈を使用するため、Program.csの先頭に using ステートメントを追加する必要があります
using System.ComponentModel.DataAnnotations;
- 次に、Username プロパティに注釈を付けて、それが主キーであることを識別します
public class User
{
[Key]
public string Username { get; set; }
public string DisplayName { get; set; }
}
- Add-Migration AddUser コマンドを使用して移行をスキャフォールディングし、これらの変更をデータベースに適用する
- Update-Database コマンドを実行して、新しい移行をデータベースに適用する
新しいテーブルがデータベースに追加されました。
EF でサポートされる注釈の完全な一覧は次のとおりです。
- KeyAttribute
- StringLengthAttribute
- MaxLengthAttribute
- ConcurrencyCheckAttribute
- RequiredAttribute
- TimestampAttribute
- ComplexTypeAttribute
- ColumnAttribute
- TableAttribute
- InversePropertyAttribute
- ForeignKeyAttribute
- DatabaseGeneratedAttribute
- NotMappedAttribute
7. Fluent API
前のセクションでは、データ注釈を使用して、規則によって検出されたものを補完またはオーバーライドする方法について説明しました。 モデルを構成するもう 1 つの方法は、Code First fluent API を使用することです。
ほとんどのモデル構成は、単純なデータ注釈を使用して行うことができます。 fluent API は、データ注釈では不可能な高度な構成に加えて、データ注釈で実行できるすべてをカバーするモデル構成を指定する、より高度な方法です。 データ注釈と fluent API を一緒に使用できます。
Fluent API にアクセスするには、DbContext の OnModelCreating メソッドをオーバーライドします。 たとえば、User.DisplayName が格納されている列の名前を display_name に変更するとします。
- BloggingContext の OnModelCreating メソッドを次のコードでオーバーライドします
public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>()
.Property(u => u.DisplayName)
.HasColumnName("display_name");
}
}
- Add-Migration ChangeDisplayName コマンドを使用して移行をスキャフォールディングし、これらの変更をデータベースに適用します。
- Update-Database コマンドを実行して、新しい移行をデータベースに適用します。
DisplayName 列の名前が display_name に変更されました。
まとめ
このチュートリアルでは、新しいデータベースを使用した Code First 開発について説明しました。 クラスを使用してモデルを定義し、そのモデルを使用してデータベースを作成し、データを格納および取得しました。 データベースが作成されたら、Code First Migrations を使用して、モデルの進化に合わせてスキーマを変更しました。 また、データ注釈と Fluent API を使用してモデルを構成する方法についても説明しました。
.NET