Entity Framework Core を使ってみる

samatsu 6/9/2016 4612 N/A Dot NET Core

Entity Framework Core はまだプレリリースの段階ですが、de:code 2016 で紹介していたので試しに使ってみました。手始めにここ を参考にコンソールアプリケーションを作成してみました。

まずは Visual Studio でコンソールアプリケーション(.NET Core)を作成してみます。

ASP.NET Core Application to Existing Database (Database First)

Entity Framework Core 用のパッケージをプロジェクトに追加す。NuGetパッケージマネージャーコンソールを起動して、次のコマンドを入力します。プレリリースなので -pre オプションを指定しています。

Install-Package Microsoft.EntityFrameworkCore.SqlServer –Pre

もちろん、NuGet パッケージマネージャーの画面で'プレリリースを含める'にチェックしてからMicrosoft.EntityFrameworkCore.SqlServerを検索してパッケージを追加することも可能です。

データベースからCode First用のクラスを生成したい場合は追加で次のパッケージもインストールする必要があるようです。詳細は冒頭で紹介したリンク先をご確認ください。
Install-Package Microsoft.EntityFrameworkCore.Tools –Pre
Install-Package Microsoft.EntityFrameworkCore.SqlServer.Design –Pre
 

記事作成段階でインストールするSQL Server 用の Entity Framework Core は不具合があるようで、出力ウィンドウに次のようなエラーメッセージが表示されます。

Errors in C:\Project\EFCoreSample\src\EFCoreSample\EFCoreSample.xproj
    Package Ix-Async 1.2.5 is not compatible with netcoreapp1.0 (.NETCoreApp,Version=v1.0). Package Ix-Async 1.2.5 supports:

githubにIssueが登録されていました。ここに記載されている回避方法で、今回は対応することにします。project.json ファイルを開いて、frameworksの設定を変更します。

  "frameworks": {
    "netcoreapp1.0": {
      "imports": "dnxcore50"
    }
  }

を次のように変更します。

  "frameworks": {
    "netcoreapp1.0": {
      "imports": "portable-net451+win8"
    }
  }

ビルドとしとりあえずエラーが発生しないことを確認しました。

次にサンプルとして使用するデータベースとテーブルを作成します。サーバーエクスプローラーで localdb\mssqllocaldb の master dbに接続して次のコマンドを実行します。

USE [master]
GO

CREATE  DATABASE [SampleDb]
GO

Use [SampleDb]

CREATE TABLE [dbo].[Book] (
    [Id]           INT            IDENTITY (1, 1) NOT NULL,
    [Title]        NVARCHAR (100) NOT NULL,
    [Publish Date] DATETIME2 (7)  NOT NULL,
    PRIMARY KEY CLUSTERED ([Id] ASC)
);

データベースの準備も完了です。あとはプログラムを作成していきます。SampleContext.cs クラスファイルを作成して次のようにCode First用のコンテキストクラスを定義してみました。単純に SampleContextクラスとBookというテーブルに対応するBookクラスを定義しただけです。Fluent API と Annotationの両方を試しに使ってみました。まぁここらへんはEntity Framework Code First と変わりがなさそうです。

using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;

namespace EFCoreSample
{
    public class SampleContext : DbContext
    {
        public virtual DbSet<Book> Books { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=SampleDb;Trusted_Connection=True");
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            // Fluent API で構成
            modelBuilder.Entity<Book>().Property(e => e.Release).IsRequired(true)
                .ForSqlServerHasColumnType("datetime2").ForSqlServerHasColumnName("Publish Date");
        }
    }

    [Table("Book")]
    public class Book
    {
        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }
        [Required, MaxLength(200)]
        public string Title { get; set; }
        public DateTime Release { get; set; }
    }
}

あとは、既定で作成されるProgram.csファイルにサンプルコードを記載して実行してみました。

namespace EFCoreSample
{
    public class Program
    {
        public static void Main(string[] args)
        {
            try { 
            using(var ctxt = new SampleContext())
            { 
                ctxt.Add(new Book { Title = "sample1", Release = DateTime.Now });
                ctxt.Add(new Book { Title = "sample2", Release = DateTime.Now });

                ctxt.SaveChanges();
            }
            }catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
            } 
        }
    }
}

Bookテーブルの中身を確認してみます。Bookテーブルを右クリック>テーブル データの表示 をクリックします。

レコードが追加されていることが分かります。

もともとEntity Frameworkは Code First を気に入っていたので Entity Framework Coreで1.0の段階からサポートされているのはありがたいですね。