ASP.NET core + angular2アプリケーションを作成する(その2)
その1はこちら
EntityFramework Core を設定する
MySQLとかも使ってみたいが、今回はSQLServerを使う。
パッケージのインストール
パッケージマネージャコンソールから
Install-Package Microsoft.EntityFrameworkCore
Install-Package Microsoft.EntityFrameworkCore.SqlServer
project.jsonに以下を追加で記述してツールをインストールする(コンソールから入れる方法どうやるんだろう)
"dependencies": {
"Microsoft.EntityFrameworkCore.Tools": {
"version": "1.0.0-preview2-final",
"type": "build"
}
}
"tools": {
"Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final",
}
適当なモデルを作る
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace core_angular2.Models
{
[Table("Notes")]
public class Note
{
[Required, Key]
public float Id { get; set; }
[Display(Name = "ノート名"), MaxLength(50)]
public string Name { get; set; }
}
}
コンテキストを作る
using Microsoft.EntityFrameworkCore;
namespace core_angular2.Models
{
public class DefaultContext : DbContext
{
public DefaultContext(DbContextOptions<DefaultContext> options)
: base(options)
{ }
public DbSet<Note> Notes { get; set; }
}
}
接続に使うクラスを作る
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using core_angular2.Models;
namespace core_angular2.Providers
{
public class EntityFrameworkConfigurationProvider : ConfigurationProvider
{
public EntityFrameworkConfigurationProvider(Action<DbContextOptionsBuilder> optionsAction)
{
OptionsAction = optionsAction;
}
Action<DbContextOptionsBuilder> OptionsAction { get; }
public override void Load()
{
var builder = new DbContextOptionsBuilder<DefaultContext>();
OptionsAction(builder);
using (var dbContext = new DefaultContext(builder.Options))
{
// dbContext.Database.EnsureCreated();
}
}
}
}
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
namespace core_angular2.Providers
{
public class EntityFrameworkConfigurationSource : IConfigurationSource
{
private readonly Action<DbContextOptionsBuilder> _optionsAction;
public EntityFrameworkConfigurationSource(Action<DbContextOptionsBuilder> optionsAction)
{
_optionsAction = optionsAction;
}
public IConfigurationProvider Build(IConfigurationBuilder builder)
{
return new EntityFrameworkConfigurationProvider(_optionsAction);
}
}
}
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
namespace core_angular2.Providers
{
public static class EntityFrameworkExtensions
{
public static IConfigurationBuilder AddEntityFrameworkConfig(
this IConfigurationBuilder builder, Action<DbContextOptionsBuilder> setup)
{
return builder.Add(new EntityFrameworkConfigurationSource(setup));
}
}
}
接続設定する
設定ファイルのひな型を作る
{
"ConnectionStrings": {
"DefaultContext": ""
}
}
開発環境用の接続設定ファイルを作る
{
"ConnectionStrings": {
"DefaultContext": "Data Source=(LocalDb)\MSSQLLocalDB"
}
}
Startup.csの最初でconnectionStringsを取得し、Configrationに設定する
(env.EnvironmentNameを使うことで環境ごとの接続文字列の定義を分けることができる)
public Startup(IHostingEnvironment env)
{
var connectionStringsConfig = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("connectionStringsSettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"connectionStringsSettings.{env.EnvironmentName}.json", optional: true)
.Build();
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddJsonFile("connectionStringsSettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"connectionStringsSettings.{env.EnvironmentName}.json", optional: true)
.AddEntityFrameworkConfig(options =>
options.UseSqlServer(connectionStringsConfig.GetConnectionString("DefaultContext")));
Configuration = builder.Build();
}
Startup.csのConfigurationServiceに追加する
public void ConfigureServices(IServiceCollection services)
{
...
services.AddEntityFrameworkSqlServer();
services.AddDbContext<DefaultContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultContext")));
}
マイグレーションしてデータベースを作る
パッケージマネージャコンソールから
Add-Migration AddNoteTable
Update-Database
SQLServerオブジェクトエクスプローラーでデータベースができていることが確認できるはず
Collationも設定しておく
Add-Migration SetDefaultCollation
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Migrations;
namespace core_angular2.Migrations
{
public partial class SetDefaultCollation : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql("ALTER DATABASE dotnetcore_angular2 SET SINGLE_USER WITH ROLLBACK IMMEDIATE;", suppressTransaction: true);
migrationBuilder.Sql("ALTER DATABASE dotnetcore_angular2 COLLATE Japanese_BIN2;", suppressTransaction: true);
migrationBuilder.Sql("ALTER DATABASE dotnetcore_angular2 SET MULTI_USER;", suppressTransaction: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}
ControllerからDbへ接続してみる
DbContextにコネクションストリング経由で取得するstaticメソッドを追加
public static DefaultContext GetBy(string connectionString)
{
var optionsBuilder = new DbContextOptionsBuilder<DefaultContext>();
optionsBuilder.UseSqlServer(connectionString);
return new DefaultContext(optionsBuilder.Options);
}
Controllerにコネクションストリングを渡すために設定モデルを追加
namespace core_angular2.Models
{
public class ConfigData
{
public string DefaultConnectionString { get; set; }
}
}
Startup.csのConfigureServicesに設定を追加する
public void ConfigureServices(IServiceCollection services)
{
...
services.Configure<ConfigData>(options =>
{
options.DefaultConnectionString = Configuration.GetConnectionString("DefaultContext");
});
}
ValuesControllerを修正してapi/values/1でDbの中身を取得してみる
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using core_angular2.Models;
namespace core_angular2.Controllers
{
[Route("api/[controller]")]
public class ValuesController : Controller
{
private DefaultContext _Db { get; set; }
public ValuesController(IOptions<ConfigData> optionsAccessor)
{
this._Db = DefaultContext.GetBy(optionsAccessor.Value.DefaultConnectionString);
}
// GET api/values
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/values/5
[HttpGet("{id}")]
public string Get(int id)
{
var note = this._Db.Notes.First();
return $"note: id={note.Id}, name={note.Name}";
}
// 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)
{
}
}
}
よし、とれた
note: id=1, name=テストノート
※ データベースには適当に値を登録しておきました
次は認証周りとかやりたい
公式ドキュメントにはお世話になっています。