1. midori44

    Posted

    midori44
Changes in title
+ASP.NET MVC + MySQL で開発環境構築
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,169 @@
+ASP.NET MVC & EntityFramework によるコードファースト開発環境を MySQL で構築してみます。
+と言っても今回はプロジェクトを作成して ASP.NET Identity によるユーザー認証を MySQL で動かすところまで。
+
+#準備
+Visual Studio 2013 Community または Professional 以上を用意。
+Express for Web では拡張機能が使えないので注意。
+
+#プロジェクト作成
+新規作成 -> プロジェクト -> Visual C# -> ASP.NET Webアプリケーション を選択。
+.NET Framework 4, 4.5 および 4.5.1 のサポートは 2016年1月12日 に終了するらしいので .NET Framework 4.5.2 を推奨。
+
+テンプレートは MVC を選択して、認証に「個人ユーザーアカウント」を使用。
+今回は「単体テストの追加」とAzureの「クラウド内のホスト」のチェックは外しておきます。
+![WS0016.jpg](https://qiita-image-store.s3.amazonaws.com/0/57132/c0b0e7d6-f2f9-3404-015f-b7228820ff12.jpeg)
+
+これで ASP.NET アプリケーションが新規作成されました。
+デバッグ実行すれば、ユーザー登録・ログインといった ASP.NET Identity の認証機能を使用できることが確認できます。
+![WS0017.jpg](https://qiita-image-store.s3.amazonaws.com/0/57132/968e7d2d-e9c8-1f8b-8e91-9335ddd91c32.jpeg)
+
+#MySQL接続
+デフォルトでは SQL Server Compact が使用されているので、接続先を MySQL に変更してみます。
+
+##MySql.Data.Entityのインストール・設定
+「NuGet パッケージの管理」から MySQL で検索して `MySql.Data.Entity` をインストールします(2015/4/14時点の最新版は6.9.6)。
+ついでに Microsoft ASP.NET MVC と EntityFramework も最新版にアップデートしておきます。
+
+次に `Web.config` を開きます(Viewsディレクトリ内の `Web.config` ではなくプロジェクト直下のほう)。
+`entityFramework` および `system.data` の設定は `MySql.Data.Entity` のインストール時に自動で追加されているので、`connectionStrings` のみ変更します。
+
+```xml:Web.config
+<connectionStrings>
+ <!-- <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-webapp-****.mdf;Initial Catalog=aspnet-webapp-****.;Integrated Security=True" providerName="System.Data.SqlClient" /> -->
+ <add name="DefaultConnection" connectionString="server=127.0.0.1;port=3306;database=test;uid=root;password=;charset=utf8" providerName="MySql.Data.MySqlClient" />
+</connectionStrings>
+```
+
+ここではXAMPP上で初期設定の MySQL を想定していますので、接続文字列のパラメータは環境に合わせて変更してください。
+
+##マイグレーション
+続いて、マイグレーションを実行して認証で使用されるテーブルをコードから自動生成します。
+
+###Enable-Migrations
+「パッケージマネージャー コンソール」から次のコマンドを実行します。
+`Enable-Migrations`
+
+Migration ディレクトリと `Configuration.cs` ファイルが作成されました。
+
+
+次に Add-Migration を実行するのですが、このまま実行すると以下のエラーが発生してしまいます。
+
+`プロバイダー 'MySql.Data.MySqlClient' で MigrationSqlGenerator が見つかりませんでした。対象の移行構成クラスで SetSqlGenerator メソッドを使用して、追加の SQL ジェネレーターを登録してください。`
+
+なので先ほど生成された `Configuration.cs` に、`DbConfiguration` の継承クラスを追加して MigrationSqlGenerator を登録します。
+
+```csharp:Configuration.cs
+using MySql.Data.Entity
+
+internal sealed class Configuration : DbMigrationsConfiguration<ApplicationDbContext>
+{
+ ...
+
+ public class MysqlConfiguration : DbConfiguration
+ {
+ public MysqlConfiguration()
+ {
+ SetMigrationSqlGenerator(MySqlProviderInvariantName.ProviderName, () => new MySqlMigrationSqlGenerator());
+ }
+ }
+}
+```
+これで Add-Migration が実行できるようになりました。
+
+###Add-Migration
+「パッケージマネージャー コンソール」から次のコマンドを実行します。
+`Add-Migration Initial`
+
+Migration ディレクトリ内に `2015****_Initial.cs` が作成されました。
+このファイルにコードから生成されたテーブルのカラム情報が保存されています。
+
+
+最後に Update-Database を実行するのですが、このまま実行すると以下のエラーが発生してしまいます。
+
+`Specified key was too long; max key length is 767 bytes`
+
+これは MySQL ではキーの長さの上限が 255 (utf-8のvarchar型)のためなので、キーとなるカラムの長さを 256 から 255 に修正します。
+
+```csharp:2015****_Initial.cs
+public override void Up()
+{
+ CreateTable(
+ "dbo.AspNetRoles",
+ c => new
+ {
+ Id = c.String(nullable: false, maxLength: 128, storeType: "nvarchar"),
+ // maxLength: 256 -> 255
+ Name = c.String(nullable: false, maxLength: 255, storeType: "nvarchar"),
+ })
+ .PrimaryKey(t => t.Id)
+ .Index(t => t.Name, unique: true, name: "RoleNameIndex");
+
+ ...
+
+ CreateTable(
+ "dbo.AspNetUsers",
+ c => new
+ {
+ Id = c.String(nullable: false, maxLength: 128, storeType: "nvarchar"),
+ Email = c.String(maxLength: 256, storeType: "nvarchar"),
+ EmailConfirmed = c.Boolean(nullable: false),
+ PasswordHash = c.String(unicode: false),
+ SecurityStamp = c.String(unicode: false),
+ PhoneNumber = c.String(unicode: false),
+ PhoneNumberConfirmed = c.Boolean(nullable: false),
+ TwoFactorEnabled = c.Boolean(nullable: false),
+ LockoutEndDateUtc = c.DateTime(precision: 0),
+ LockoutEnabled = c.Boolean(nullable: false),
+ AccessFailedCount = c.Int(nullable: false),
+ // maxLength: 256 -> 255
+ UserName = c.String(nullable: false, maxLength: 255, storeType: "nvarchar"),
+ })
+ .PrimaryKey(t => t.Id)
+ .Index(t => t.UserName, unique: true, name: "UserNameIndex");
+
+ ...
+}
+```
+もう一箇所、マイグレーション履歴を保持する `__migrationhistory` テーブルも修正する必要があります。
+先ほどの `Configuration.cs` に `HistoryContext` の継承クラスを作成してキーの長さを変更します。
+
+```csharp:Configuration.cs
+public class MysqlConfiguration : DbConfiguration
+{
+ public MysqlConfiguration()
+ {
+ SetMigrationSqlGenerator(MySqlProviderInvariantName.ProviderName, () => new MySqlMigrationSqlGenerator());
+
+ SetHistoryContext("MySql.Data.MySqlClient", (dbConnection, defaultSchema) => new MysqlHistoryContext(dbConnection, defaultSchema));
+ }
+ public class MysqlHistoryContext : HistoryContext
+ {
+ public MysqlHistoryContext(DbConnection dbConnection, string defaultSchema)
+ : base(dbConnection, defaultSchema)
+ {
+ }
+
+ protected override void OnModelCreating(DbModelBuilder modelBuilder)
+ {
+ base.OnModelCreating(modelBuilder);
+
+ modelBuilder.Entity<HistoryRow>().Property(h => h.MigrationId).HasMaxLength(255).IsRequired();
+ modelBuilder.Entity<HistoryRow>().Property(h => h.ContextKey).HasMaxLength(255).IsRequired();
+ }
+ }
+}
+```
+
+これで Update-Database が実行できるようになりました。
+
+###Update-Database
+「パッケージマネージャー コンソール」から次のコマンドを実行します。
+`Update-Database`
+
+
+以上で MySQL にデータベースが生成されます。
+![WS0020.jpg](https://qiita-image-store.s3.amazonaws.com/0/57132/17f48e04-fcd3-3393-8089-33308638e815.jpeg)
+
+
+
+デバッグ実行してユーザー登録すれば `aspnetusers` テーブルが更新されることが確認できます。