Entity Framework Core (Entity Framework 7)を試してみる
いつの間にやらEntity Framework Coreがリリースされてたのですね。 Entity Framework Core を試しつつ、Entity Framework 6.xとの違いを見ていこうと思います。
Sqliteが公式になってる
公式サイトのDatabase ProviderにSqliteの文字が!
EntityFramework/README.md at dev · aspnet/EntityFramework · GitHub
EntityFrameworkの中の人が作ってるのかな? SQLServerはLocalDBがあるとは言え、割と重いですし、 ファイルを消すだけでさくっとDBを消せるSqliteは魅力です。 単体テストも書きやすいですしね。 単体テストに関してはInMemoryが追加されたので、気になるところ。
SqliteでMigrationに対応してる!
今まではCode Firstでテーブルを作ることはできましたが、 モデルの変更を検知して既存のテーブルに差分を適用する、 なんてことはできませんでした。
これができるのがSQLServerだけだったイメージです。 それが、公式になっているせいかSQLiteも対応していました。
もしかすると共有の機能が強化され、他のDBでもできるかもしれません。
SqliteでDateTimeOffsetに対応してる
日付を扱ううえでDateTimeOffsetを使うことがあります。 Entity Framework 6.xではSqliteの場合はDateTimeOffset型は非対応でした。 Entity Framework Coreでは、一応使えました。 ただし、Offset(タイムゾーンを表す)は0にすること、が要件のようなので 実質DateTimeとかわりません。 しかし、SQLServerとSqliteで同じデータモデルが使えるのが良いかもしれません。 もう少し調べたいところですが。
Select句が柔軟になってる!
Entity Framework 6.xではSelectメソッド、WhereメソッドはSQLに変換されるため、 C#のラムダ式とはいえ割と制限がありました。 例えば、こんな呼び方はエラーになります。
class Program
{
static void Main(string[] args)
{
using (var context = new TempContext())
{
var people = context.People.Select(_ => new PersonDomainModel(_.Id, _.Name)); //<-複雑なSelectメソッド
}
}
}
public class TempContext : DbContext
{
public DbSet<Person> People { get; set; }
//(略)
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
public class PersonDomainModel
{
public PersonDomainModel(int id, string name)
{
Id = id;
Name = name;
}
public int Id { get; }
public string Name { get; }
}
この制限がわかりにくくて、ランタイムエラーになるのが気になっていました。
それが、Entity Framework Coreではさらっと通ります。 しかもログを出してみると、ちゃんと必要なColumnだけクエリされてるっぽい。
SELECT TOP(1) [].[Id], [].[Name] FROM [People] AS [_]
Selectメソッドの式木を解析して、使われているColumnだけSQLに変換しているのでしょう。 ただし、Whereメソッドは全レコードをC#側で実行されるようなので Whereメソッドは注意が必要です。
この機能は、Client Evaluation というのかな?
Client vs. Server Evaluation — Entity Framework Core 1.0.0 documentation
設定でOffにできるようですが、WhereメソッドだけOffにできたらいいんだけどできるのかな?
Database.SetInitializerが無い
SQLServerの場合、こんな感じ書くと起動時にデータベースをクリアしてくれました。
Database.SetInitializer(new DropCreateDatabaseAlways<EntitiesContext>());
また、データモデルからテーブルを自動Migrationなんてこともできたはず。 この機能は無くなっていました。
Visual Studioのパッケージマネージャコンソールでコマンドを打ち込むことでデータベースは更新するようです。
Add-Migration
Update-Database
ただ、この機能を使うにはNugetで Microsoft.EntityFrameworkCore.Tools を追加する必要がありますが、 2016/7/23現在、Pre-Releaseのようです。
.NET Core CLI ?
.NET Core CLI というキーワードがちょいちょい出てきます。
.NET - Powerful Open Source Development
この.NET Core CLIでもデータベースの更新ができるようです。 まだ使ったことはないのですが、上のMigrationを使うのにVisual Studioが必要なので Visual Studio無しでデータベースを更新する仕組みなんですかね?