EF CoreでモデルファーストでDBを扱う手順
www.entityframeworktutorial.net
Entity Framework Core : DbContext
DbContextはDBとのやりとりを担う.
DBのエンティティのインスタンスを取得,保存するためのもの.
DbContextはUnit Of WorkとRepository Patternの考えを組み合わせたもの.
EF CoreのDbContextは以下の役割を果たす.
アプリケーションでDbContextを使用するには,DbContextを継承したクラスを作る必要があり,Contextクラスと言われる.
ContextクラスはしばしばDbSet
以下のContextクラスの例について考える.
public class SchoolContext : DbContext { public SchoolContext() { } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { } protected override void OnModelCreating(ModelBuilder modelBuilder) { } //entities public DbSet<Student> Students { get; set; } public DbSet<Course> Courses { get; set; } }
SchoolContextクラスはDbContextクラスを継承し,StudentとCourseというDbSet
OnConfiguringメソッドとOnModelCreatingメソッドをオーバーライドする.
DBと接続し,StudentやCourseのデータの検索,取得を行うためには,このSchoolContextのインスタンスを生成する必要がある.
OnConfiguring()メソッドによって,DbContextOptionsBuilderを介してContext データソースを選択,設定する.
どのようにDbContextクラスを設定するかはここが参考になる.
OnModelCreating()メソッドによって,ModelBuilderのFluent APIを介してモデルの設定をする.
First EF Core Consoleアプリケーション
ここではコードファーストでのEntity Framework Coreの使い方をステップバイステップ学んでいく.
.NET Core ConsoleアプリケーションをVisual Studio 2017を使って作成する.
.NET Core ConsoleアプリケーションはVS2017かコマンドラインから作成できる.ここではVS2017を使う.
EntityFrameworkCore.SqlServerをNugetでインストールする.
モデルを作る.
public int StudentId { get; set; } public string Name { get; set; } [Required] public int CourseId { get; set; } public Course Course { get; set; }//ナビゲーションプロパティ } public class Course { public int CourseId { get; set; } public string CourseName { get; set; } public ICollection<Student> Students { get; set; }//ナビゲーションプロパティ }
DbContextを作る
public class SchoolContext : DbContext { public DbSet<Student> Students { get; set; } public DbSet<Course> Courses { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer(@"Server=.\SQLEXPRESS;Database=SchoolDB;Trusted_Connection=True;"); } }
このContextクラスは2つのDbSet
OnConfiguringメソッドの中で,DbContextOptionsBuilderのインスタンスはどのDBを使用するかを記述するために用いられる.
UseSqlServerメソッドの中の「Server=.\SQLEXPRESS;Database=SchoolDB;Trusted_Connection=True;」は接続文字列といい,DBの情報を表す.
Server=
は使用するDBサーバーを,Database=
は作成するDBの名前,そしてTrusted_Connection=True
はWindows認証モードを表す.
EF Coreはこの接続文字列を使用して,マイグレーション時にDBを作成する.
Contextとエンティティクラスを作成したら,マイグレーションによってDBを作成するときです.
マイグレーション
EF CoreはDBをモデルを介して作成,更新するための複数のマイグレーションコマンドがある.
dotnet ef migrations add CreateSchoolDB
この時点ではDBはまだ作成されていない.
次に,
dotnet ef database update
ここでDBが作成される.
UseSqlServer()メソッドに記述された接続文字列の内容に従ってDBが作成される.
接続文字列はappsettings.json
などの設定ファイルに記述してもよいし,直接UseSqlServer
メソッドに渡してもよい.
"ConnectionStrings": { "EmployeeDbConnection": "server=(localdb)\\MSSQLLocalDB;database=EmployeeDB;Trusted_Connection=true" }
設定ファイル経由の場合は以下のようにUseSqlServerにわたす.
services.AddDbContextPool<AppDbContext>(
options => options.UseSqlServer(_config.GetConnectionString("EmployeeDbConnection")));
DbSetプロパティの名前でテーブルが作成される.StudentsやCourses.
以下のようにDBサーバーへ接続すると,DB及びテーブルが作成されていることが確認できる.
ssms
Visual StudioのSQL Server Object Explorer
DBの読み書き
Entity Framework Coreによるクエリ
書き込み
var newStudent = new Student { Name = "John", }; context.Students.Add(newStudent); await context.SaveChangesAsync();
読み込み
EF CoreはLinq-to-Entities(L2E)に新しい機能がある.これはEF 6にはなかったもの.
var studentsWithSameName = context.Students .Where(s => s.Name == GetName()) .ToList();
このようにLinq形式でDBからデータを取得できる.
Eager Loading
レコードのリレーション先のレコードも一括で取得すること.
レコードを取得して,その外部キーを使って別のテーブルから関連するデータを取得すると,すべてのレコードに対して外部キーを使ったクエリが発生してしまう.(N+1問題)
Include
メソッドを使う.
var studentWithCourse =await context.Students .Include(s => s.Course) .FirstOrDefaultAsync();
ThenInclude
3.1ではナビゲーションプロパティにvirtualをつけなくてもいい?