ASP.NET MVC 6 でデータベースに接続(データベースファースト編)

前回の続きで、今度はデータベースから構築するパターン。基本的なところは、ASP.NET5 MVC6 Entity Framework 7 を使って Database First する と同じで、あらかじめ SQL Server で作ったテーブルをもとに ASP.NET MVC の Model クラスを作る。

ASP.NET MVC 6 の Web Application テンプレートを使う

こちらも、Web Application のテンプレートを使う。無駄なページができるのは仕方がないのだが、project.json などの設定がそのまま使えるので活用する。

SSMS(SQL Server Mangement Studio)でテーブルを作成する

ここではローカルPCに SQL Server を入れて testdb に「Movie」というテーブルを作っている。前回のとテーブル名を合わせると比較しやすい、ってのとどうやらテーブルに主キーとIDENTITYが設定していないと Model クラスの作成に失敗するので、元の Movie クラスから引っこ抜いている。

テーブル作成時にスクリプトはこんな感じ。

USE [testdb]
GO

/****** Object:  Table [dbo].[Movie]    Script Date: 2016/02/04 0:31:47 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Movie](
	[ID] [int] IDENTITY(1,1) NOT NULL,
	[Genre] [nvarchar](max) NULL,
	[Price] [decimal](18, 2) NOT NULL,
	[ReleaseDate] [datetime2](7) NOT NULL,
	[Title] [nvarchar](max) NULL,
 CONSTRAINT [PK_Movie] PRIMARY KEY CLUSTERED 
(
	[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO

ちなみに、最近の SSMSは後から列名の変更をしたり、IDENTITYの設定をし直したりできない。昔はできたような気がするのだが、最近の SSMSを使うとエラーになる。SQL Server のスクリプトで直接「alter table …」を使うと変更ができるので SQL Server 側の制限ではないらしい。MySQL の Workbench では自由にできるのでかなり残念。

…と思い続けていたのだけど、SSMSのオプションで [デザイナー] 部の [テーブルの再作成を必要とする変更を保存できないようにする] とできるようになる。これはハッピー。

project.json に EntityFramework.MicrosoftSqlServer.Design を追加する

SQL Server から Model クラスを作るときは「EntityFramework.MicrosoftSqlServer.Design」が必要なので、NuGet から取得しておく。
取得しないまま、「dnx ef …」をすると、きちんとエラーを返してくれるので、それに従ってもよい。

Unable to find design-time provider assembly. Please install the EntityFramework.MicrosoftSqlServer.Design NuGet package and ensure that the package is referenced by the project.

dnx ef で Model クラスを作る

ちょっとややこしいけど、次のように書くと Models フォルダに対象データベース内にあるテーブルの EF を作ってくれる。

dnx ef dbcontext scaffold "Server=.;Database=testdb;Trusted_Connection=True" EntityFramework.MicrosoftSqlServer --outputDir Models

Azure とかにつなぐ場合は(たぶん)接続文字列を変えればよい。出力先は、–outputDir で指定して今回は Models フォルダ内にしてある。

これを動かすと、Visual Studio のほうに EF クラスと接続のための testdbContext クラスを作ってくれる。接続用のクラスは、「データベース名」+「Context」になるようだ。

スキャフォールディングで、Controller と View を作る

Model クラスができたので Controller と View を自動生成させる。
「追加」→「コントローラー」を選択して、「Entity Framework を使用したビューがある~」のほうを選ぶ。

モデルクラスで「Movie」を選んで、データコンテキストクラスでは「testdbContext」のほうを選ぶ。

ちなみに、testdbContext クラスは、元のテンプレートにある ApplicationDbContext と同等の機能を持つデータコンテキストクラス。接続先のデータベースがハードコーディングされているので、デフォルトでここに直結という感じになっている。きちんと手を加えれば、ApplicationDbContext と同じように applications.json から読み込めるようにできるだろう。

public partial class testdbContext : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder options)
    {
        options.UseSqlServer(@"Server=.;Database=testdb;Trusted_Connection=True");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Movie>(entity =>
        {
            entity.Property(e => e.Price).HasColumnType("decimal");
        });

        modelBuilder.Entity<person>(entity =>
        {
            entity.Property(e => e.name)
                .IsRequired()
                .HasMaxLength(50)
                .HasColumnType("varbinary");
        });
    }

    public virtual DbSet<Movie> Movie { get; set; }
}

データベース接続のために Setup.cs を書き換える

データベースコンテキストを使って接続するので、Setup.cs に AddDbContext なところを書き加える。

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddEntityFramework()
        .AddSqlServer()
        .AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));

	// ここを追加する
    services.AddEntityFramework()
            .AddSqlServer()
            .AddDbContext<testdbContext>();

    services.AddIdentity<ApplicationUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders();

    services.AddMvc();

    // Add application services.
    services.AddTransient<IEmailSender, AuthMessageSender>();
    services.AddTransient<ISmsSender, AuthMessageSender>();
}

実行してみる

動かしてみた結果がこれ。コードファーストのときと同じように CRUD を動かすことができる。

SSMS を使って select してデータ確認もできる。

カテゴリー: ASP.NET パーマリンク

ASP.NET MVC 6 でデータベースに接続(データベースファースト編) への2件のフィードバック

  1. ぽぴ王子 のコメント:

    初めまして。いつも拝見させていただいています。
    内容の本筋とは関係ないのですが
    > ちなみに、最近の SSMSは後から列名の変更をしたり、IDENTITYの設定をし直したりできない。
    > 昔はできたような気がするのだが、最近の SSMSを使うとエラーになる。
    の部分についてです。
    もしかするとですが、SSMSのオプションで [デザイナー] 部の [テーブルの再作成を必要とする変更を保存できないようにする]
    にチェックが入っていたりしませんでしょうか。
    このオプション設定はデフォルトでチェックありなので、いつもインストールするたびにテーブルに変更を加えようとして
    怒られることが多いので。
    的はずれなことを言ってしまっているかもしれません。その場合はご容赦ください。

    • masuda のコメント:

      ありがとうございます。
      > SSMSのオプションで [デザイナー] 部の [テーブルの再作成を必要とする変更を保存できないようにする]
      で無事できました。記事のほうを直しておきます。

コメントは停止中です。