前回の続きで、今度はデータベースから構築するパターン。基本的なところは、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 クラスから引っこ抜いている。
テーブル作成時にスクリプトはこんな感じ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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 …」をすると、きちんとエラーを返してくれるので、それに従ってもよい。
1 | 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 を作ってくれる。
1 | 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 から読み込めるようにできるだろう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 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 なところを書き加える。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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 してデータ確認もできる。
初めまして。いつも拝見させていただいています。
内容の本筋とは関係ないのですが
> ちなみに、最近の SSMSは後から列名の変更をしたり、IDENTITYの設定をし直したりできない。
> 昔はできたような気がするのだが、最近の SSMSを使うとエラーになる。
の部分についてです。
もしかするとですが、SSMSのオプションで [デザイナー] 部の [テーブルの再作成を必要とする変更を保存できないようにする]
にチェックが入っていたりしませんでしょうか。
このオプション設定はデフォルトでチェックありなので、いつもインストールするたびにテーブルに変更を加えようとして
怒られることが多いので。
的はずれなことを言ってしまっているかもしれません。その場合はご容赦ください。
ありがとうございます。
> SSMSのオプションで [デザイナー] 部の [テーブルの再作成を必要とする変更を保存できないようにする]
で無事できました。記事のほうを直しておきます。