EF7がSQLiteで間違った移行を起こす

c# dnx entity-framework-core migration sqlite

質問

Entity Framework 7とSQLiteでASP.Net 5を使用しようとしましたが、私はmigratorの奇妙な動作を発見しました。

私はVisual Studio 2015を使って、 "ASP.NET 5 Template Web Application"というテンプレートを使って新しいプロジェクトを作成しました。

その後、私は依存関係を取り除いた

"EntityFramework.MicrosoftSqlServer": "7.0.0-rc1-final"

また、2つの依存関係が追加され、リストアパッケージと呼ばれていました。

"EntityFramework.Sqlite": "7.0.0-rc1-final",
"Microsoft.Data.Sqlite": "1.0.0-rc1-final"

そのように

"dependencies": {
"EntityFramework.Commands": "7.0.0-rc1-final",
"EntityFramework.Sqlite": "7.0.0-rc1-final",
"Microsoft.Data.Sqlite": "1.0.0-rc1-final",
"Microsoft.AspNet.Authentication.Cookies": "1.0.0-rc1-final",
"Microsoft.AspNet.Diagnostics.Entity": "7.0.0-rc1-final",
"Microsoft.AspNet.Identity.EntityFramework": "3.0.0-rc1-final",
"Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final",
"Microsoft.AspNet.Mvc": "6.0.0-rc1-final",
"Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-rc1-final",
"Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
"Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final",
"Microsoft.AspNet.Tooling.Razor": "1.0.0-rc1-final",
"Microsoft.Extensions.CodeGenerators.Mvc": "1.0.0-rc1-final",
"Microsoft.Extensions.Configuration.FileProviderExtensions": "1.0.0-rc1-final",
"Microsoft.Extensions.Configuration.Json": "1.0.0-rc1-final",
"Microsoft.Extensions.Configuration.UserSecrets": "1.0.0-rc1-final",
"Microsoft.Extensions.Logging": "1.0.0-rc1-final",
"Microsoft.Extensions.Logging.Console": "1.0.0-rc1-final",
"Microsoft.Extensions.Logging.Debug": "1.0.0-rc1-final",
"Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0-rc1-final"
}

次にStartup.csに行き、そのような機能のConfigurationServicesを変更しました

 public void ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        var dbFilePath =     Path.Combine(PlatformServices.Default.Application.ApplicationBasePath, "test.db");
        services.AddEntityFramework()
         .AddSqlite()
         .AddDbContext<ApplicationDbContext>(options =>
             options.UseSqlite("Filename=" + dbFilePath));
        System.Console.WriteLine("Use DB file:" + dbFilePath);

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

        services.AddMvc();

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

それから、「Migrations」フォルダからすべてのファイルを削除し、そのソリューションを構築しました。すべてが移行を作成する準備が整いました。プロジェクトフォルダーと次のコマンドでgit bashを実行しました:

blush@BLUSH /d/dev/testMVC
$ dnx ef migrations add firstMigration
Use DB file:D:\dev\testMVC\test.db
Done. To undo this action, use 'ef migrations remove'

そして

$ dnx ef database update
Use DB file:D:\dev\testMVC\test.db
Applying migration '20160304130532_firstMigration'.
Done.

OK、私はデータベースファイルと "Migrations"フォルダのファイルを見ました。そして、次の生成された移行は、オブジェクトモデルを変更することなく空になると思います。私はそれをやろうとして、次のコマンドを入力しようとしました:

$ dnx ef migrations add testMigration
Use DB file:D:\dev\testMVC\test.db
Done. To undo this action, use 'ef migrations remove'

私は、生成された移行クラスを見に行きました。私はこのコードを見ました:

 protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropForeignKey(name: "FK_IdentityRoleClaim<string>_IdentityRole_RoleId", table: "AspNetRoleClaims");
            migrationBuilder.DropForeignKey(name: "FK_IdentityUserClaim<string>_ApplicationUser_UserId", table: "AspNetUserClaims");
            migrationBuilder.DropForeignKey(name: "FK_IdentityUserLogin<string>_ApplicationUser_UserId", table: "AspNetUserLogins");
            migrationBuilder.DropForeignKey(name: "FK_IdentityUserRole<string>_IdentityRole_RoleId", table: "AspNetUserRoles");
            migrationBuilder.DropForeignKey(name: "FK_IdentityUserRole<string>_ApplicationUser_UserId", table: "AspNetUserRoles");
            migrationBuilder.AddForeignKey(
                name: "FK_IdentityRoleClaim<string>_IdentityRole_RoleId",
                table: "AspNetRoleClaims",
                column: "RoleId",
                principalTable: "AspNetRoles",
                principalColumn: "Id",
                onDelete: ReferentialAction.Cascade);
            migrationBuilder.AddForeignKey(
                name: "FK_IdentityUserClaim<string>_ApplicationUser_UserId",
                table: "AspNetUserClaims",
                column: "UserId",
                principalTable: "AspNetUsers",
                principalColumn: "Id",
                onDelete: ReferentialAction.Cascade);
            migrationBuilder.AddForeignKey(
                name: "FK_IdentityUserLogin<string>_ApplicationUser_UserId",
                table: "AspNetUserLogins",
                column: "UserId",
                principalTable: "AspNetUsers",
                principalColumn: "Id",
                onDelete: ReferentialAction.Cascade);
            migrationBuilder.AddForeignKey(
                name: "FK_IdentityUserRole<string>_IdentityRole_RoleId",
                table: "AspNetUserRoles",
                column: "RoleId",
                principalTable: "AspNetRoles",
                principalColumn: "Id",
                onDelete: ReferentialAction.Cascade);
            migrationBuilder.AddForeignKey(
                name: "FK_IdentityUserRole<string>_ApplicationUser_UserId",
                table: "AspNetUserRoles",
                column: "UserId",
                principalTable: "AspNetUsers",
                principalColumn: "Id",
                onDelete: ReferentialAction.Cascade);
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
       ... 
       }

この移行を適用しようとすると、次のエラーメッセージが表示されます。

$ dnx ef database update
Use DB file:D:\dev\testMVC\test.db
Applying migration '20160304133144_testMigration'.
System.NotSupportedException: SQLite cannot support this migration operation.
   в Microsoft.Data.Entity.Migrations.SqliteMigrationsSqlGenerator.Generate(Drop
ForeignKeyOperation operation, IModel model, RelationalCommandListBuilder builde
r)
   в Microsoft.Data.Entity.Migrations.MigrationsSqlGenerator.<>c.<.cctor>b__50_1
0(MigrationsSqlGenerator g, MigrationOperation o, IModel m, RelationalCommandLis
tBuilder b)
   в Microsoft.Data.Entity.Migrations.MigrationsSqlGenerator.Generate(MigrationO
peration operation, IModel model, RelationalCommandListBuilder builder)
   в Microsoft.Data.Entity.Migrations.MigrationsSqlGenerator.Generate(IReadOnlyL
ist`1 operations, IModel model)
   в Microsoft.Data.Entity.Migrations.SqliteMigrationsSqlGenerator.Generate(IRea
dOnlyList`1 operations, IModel model)
   в Microsoft.Data.Entity.Migrations.Internal.Migrator.GenerateUpSql(Migration
migration)
   в Microsoft.Data.Entity.Migrations.Internal.Migrator.<>c__DisplayClass12_4.<G
etMigrationCommands>b__10()
   в Microsoft.Data.Entity.Migrations.Internal.Migrator.Migrate(String targetMig
ration)
   в Microsoft.Data.Entity.Design.MigrationsOperations.UpdateDatabase(String tar
getMigration, String contextType)
   в Microsoft.Data.Entity.Commands.Program.Executor.<>c__DisplayClass7_0.<Updat
eDatabase>b__0()
   в Microsoft.Data.Entity.Commands.Program.Executor.Execute(Action action)
SQLite cannot support this migration operation.

それは問題です。私はこの問題を解決するために何をしなければなりませんか?

受け入れられた回答

これはSQLiteの制限です。 EFのSQLite制限を参照してください。

これは、SQLite自体が "FOREIGN KEYを追加"をサポートしていないために発生します。これを回避する方法は、テーブルを再構築することです。 他の種類のテーブルスキーマの作成 sqlite.orgの変更は、これを行うためのクエリをどのように構造化するかを指示します。あなたはこれがSQLite上でいかに乱雑で、なぜEFがこれを自動化しないのかをすぐに知ることができます。

SQLiteデータベースにデータが必要ない場合は、単に削除してcontext.Database.EnsureCreated()を使用して、新しいモデルを使用してテーブルをゼロから再構築するほうが良いでしょう。


人気のある回答

Mac用のVisual Studio Community 2017を使用している間、この問題は私に起こりました

最も簡単な方法は、データベースを削除して移行を再作成することでした。プロジェクトは開発の初期段階にあるので、もちろん私はそれを買う余裕がありました。

  1. データベースファイル(app.db)を削除します。
  2. 最初の移行のみが行われるまで( 00000000000000_CreateIdentitySchema )、 dotnet ef migrations removeコマンドを発行します。
  3. 新しい移行dotnet ef migrations add CreatedEntities (たとえば)
  4. データベースdotnet ef database update


Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ