1. midori44

    動作環境の追記

    midori44
Changes in tags
Changes in body
Source | HTML | Preview
@@ -1,169 +1,174 @@
ASP.NET MVC & EntityFramework によるコードファースト開発環境を MySQL で構築してみます。
と言っても今回はプロジェクトを作成して ASP.NET Identity によるユーザー認証を MySQL で動かすところまで。
+(2015.10.22 追記)
+Visual Studio 2015 + .NET Framework 4.6 でも動作確認。
+現在 beta 8 が公開中の ASP.NET 5 (ASP.NET MVC 6) は、まだ MySql.Data.Entity が対応していないので 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` テーブルが更新されることが確認できます。