LoginSignup
3
6

More than 5 years have passed since last update.

ASP.NET Core + angular2でやってみよう(その2) EF Coreの設定とか

Last updated at Posted at 2016-07-13

ASP.NET core + angular2アプリケーションを作成する(その2)

その1はこちら

作業リポジトリはこちら

EntityFramework Core を設定する

MySQLとかも使ってみたいが、今回はSQLServerを使う。

パッケージのインストール

パッケージマネージャコンソールから

Install-Package Microsoft.EntityFrameworkCore
Install-Package Microsoft.EntityFrameworkCore.SqlServer

project.jsonに以下を追加で記述してツールをインストールする(コンソールから入れる方法どうやるんだろう)

project.json
"dependencies": {
  "Microsoft.EntityFrameworkCore.Tools": {
    "version": "1.0.0-preview2-final",
    "type": "build"
  }
}

"tools": {
  "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final",
}

適当なモデルを作る

Models/Note.cs
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; }
    }
}

コンテキストを作る

Models/DefaultContext.cs
using Microsoft.EntityFrameworkCore;

namespace core_angular2.Models
{
    public class DefaultContext : DbContext
    {
        public DefaultContext(DbContextOptions<DefaultContext> options)
            : base(options)
        { }

        public DbSet<Note> Notes { get; set; }
    }
}

接続に使うクラスを作る

Providers/EntityFrameworkConfigurationProvider.cs
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();
            }
        }
    }
}
EntityFrameworkConfigurationSource.cs
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);
        }
    }
}
EntityFrameworkExtensions.cs
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));
        }
    }
}

接続設定する

設定ファイルのひな型を作る

ConnectionStringsSettings.json
{
  "ConnectionStrings": {
    "DefaultContext": ""
  }
}

開発環境用の接続設定ファイルを作る

ConnectionStringsSettings.json
{
  "ConnectionStrings": {
    "DefaultContext": "Data Source=(LocalDb)\MSSQLLocalDB"
  }
}

Startup.csの最初でconnectionStringsを取得し、Configrationに設定する

(env.EnvironmentNameを使うことで環境ごとの接続文字列の定義を分けることができる)

Startup.cs
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にコネクションストリングを渡すために設定モデルを追加

Models/ConfigData.cs
namespace core_angular2.Models
{
    public class ConfigData
    {
        public string DefaultConnectionString { get; set; }
    }
}

Startup.csのConfigureServicesに設定を追加する

Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    ...

    services.Configure<ConfigData>(options =>
    {
        options.DefaultConnectionString = Configuration.GetConnectionString("DefaultContext");
    });
}

ValuesControllerを修正してapi/values/1でDbの中身を取得してみる

Controllers/ValuesController.cs
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=テストノート

※ データベースには適当に値を登録しておきました

次は認証周りとかやりたい

公式ドキュメントにはお世話になっています。

3
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
6