ASP.NET Core × Entity Framework × SQLite

ちょいメモ。
ASP.NET CoreでEntityFrameWorkでSQLiteを使えるようにするところまで。

プロジェクトの準備

Visual Studio 2017から、今回は「ASP.NET Core Web API」としてプロジェクト作成。
.NET Core 2.0。

NuGetから以下のパッケージをインストールしておく。
・Microsoft.EntityFrameworkCore.Tools
・Microsoft.EntityFrameworkCore.Sqlite

テーブル準備

DbContextを継承したクラスを作成する。
この中でOnConfiguringをオーバーライドして、SQLiteデータファイルへの接続文字列を指定する。
SQLiteの接続文字列はとてもシンプルだ。
「data.db」というファイルをドキュメントルート直下に置く場合は以下のように。

public class MyDbContext : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        base.OnConfiguring(optionsBuilder);

        optionsBuilder.UseSqlite(@"Data Source='data.db'");
    }
}

ここではID, 年齢, 名前だけのPersonテーブルを作るとしましょう。
まず、そのレコードを格納するためのデータクラスを用意する。コードファースト。

public class Person
{
    public int Id { get; set; }
    public int Age { get; set; }
    public string Name { get; set; }
}

コンテキストクラスに、対応するDbSetプロパティを追加。

public class MyDbContext : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        base.OnConfiguring(optionsBuilder);

        optionsBuilder.UseSqlite(@"Data Source='data.db'");
    }

    public DbSet<Person> Persons { get; set; }
}

ここまでコードを作ってから、Microsoft.EntityFrameworkCore.Toolsを利用して、マイグレーションでテーブルを作成する。
Visual Studioのパッケージ・マネージャー・コンソールから、以下コマンドを実行。

PM> Add-Migration InitPersonTable
PM> Update-Database

(「InitPersonTable」の部分は任意の名前)

Migrationsフォルダ配下のマイグレーション管理クラスと、SQLiteのデータファイル data.db が生成される。

テーブル読み書き

さて、ASP.NET Core Web APIのプロジェクトテンプレートには、以下のようなサンプルのコントローラクラスが用意されているかと思います。

[Route("api/[controller]")]
public class ValuesController : Controller
{
    // GET api/values
    [HttpGet]
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }

    // GET api/values/5
    [HttpGet("{id}")]
    public string Get(int id)
    {
        return "value";
    }

    // POST api/values
    [HttpPost]
    public void Post([FromBody]string value)
    {
    }

    // PUT api/values/5
    [HttpPut("{id}")]
    public void Put(int id, [FromBody]string value)
    {
    }

    // DELETE api/values/5
    [HttpDelete("{id}")]
    public void Delete(int id)
    {
    }
}

これを使って、getとpostを試してみましょう。

まずは、何もいじらずに立ち上げてみる。

Visual StudioからそのままIIS Expressでデバッグ起動でも良いけど、一応デプロイ用のファイルをローカルフォルダに出力してみる。
ソリューションエクスプローラーからプロジェクト右クリック > [発行] > [フォルダー]選んでパス入力 > [発行]

しかしこのままだとさっきのdata.dbが発行先にコピーされない。
これは自分でdata.db右クリック > [プロパティ] > [出力ディレクトリにコピー] で設定すんのかな。

発行されたら、dotnetコマンドで起動。

>dotnet プロジェクト名.dll

ブラウザから http://localhost:5000/api/values/1234 にアクセスしてみる。
サンプルのままなら、なんのIDを指定しても固定で「value」だけ表示されるはず。

では、ちゃんとPersonテーブルから名前を返しましょう。
IDを引数にとるgetメソッドを以下のように書き換える。

[HttpGet("{id}")]
public IActionResult Get(int id)
{
    using (var context = new MyDbContext())
    {
        var person = context.Persons.FirstOrDefault(p => p.Id == id);
        if (person == null) return NotFound();

        return new ObjectResult(person) as IActionResult;
    }
}

もっかい立ち上げなおしてアクセスしてみる。
テーブルにはまだレコードがないので、404 NotFoundのページになればOK。

では、POSTでレコードを登録しましょう。

まずPostメソッドを以下のように書き換える。

[HttpPost]
public IActionResult Post([FromBody]Person person)
{
    if (person == null) return BadRequest();

    using (var db = new MyDbContext())
    {
        db.Persons.Add(person);
        db.SaveChanges();
    }

    return CreatedAtRoute("values", new { id = person.Id }, person);
}

Postの応答ではstatus 201で、新しく登録されたリソースへのルートを返すのが良いらしいので、上の例ではそのようにしている。
CreatedAtRouteの引数でvaluesというルート名を指定してるけど、この名前はGETメソッドのほうにつけておかないといけない。

[HttpGet("{id}", Name ="values")]
public IActionResult Get(int id)
{
    (省略)
}

呼び出し例

では、このAPIの呼び出しも別アプリとして作ってみましょう。
適当なコンソールアプリで↓こんなのを。詳しくは HttpClientでJSONデータをPOSTする をどうぞ。

var person = "{ \"Id\" : 123,  \"Age\" : 20, \"Name\" : \"鈴木一郎\"  }";

using (var client = new HttpClient())
{
    var content = new StringContent(person, Encoding.UTF8, "application/json");
    var res = client.PostAsync("http://localhost:5000/api/values", content).Result;

    Console.WriteLine(res);
}

結果。

StatusCode: 201, ReasonPhrase: 'Created', Version: 1.1, Content: System.Net.Http.NoWriteNoSeekStreamContent, Headers:
{
  Date: Mon, 12 Feb 2018 10:00:33 GMT
  Transfer-Encoding: chunked
  Location: http://localhost:5000/api/Values/123
  Server: Kestrel
  Content-Type: application/json; charset=utf-8
}

とりあえずここまで。

参考:
EntityFrameworkCoreを.NET Core コンソールアプリでCodeFirstに使う
ASP.NET Core と Visual Studio for Windows で Web API を作成する

シェアする

  • このエントリーをはてなブックマークに追加

フォローする