2017-10-14 15 views
0

MVC Identity Entity Frameworkモデルが壊れていると思われ、モデルの更新ができません。 IdentityDbContextを使用して作成されたエンティティフレームワークモデルは更新できないようです。MVC Identity Entity Frameworkモデルの更新に失敗しました - 「既にオブジェクトです」エラー

私はMVC IdentityとEFを、運用データベースと開発データベースと共に使用しています。セットアップは標準です - プロジェクト - モデル、EF構成、DbSets、EFクラス。 devデータベースを作成するには、以下の簡単なプログラムがあります。私はこの基本的な構成を長い間問題なく使用してきました。しかし、MVC Identityに移行した後、新しいクラスをモデルに追加してdevデータベースを更新することができなくなりました。 IdentityDbContextへの参照をプレーンなDbContextに置き換えると、エラーが取り除かれます。私が間違っていることを驚かす。

これが関連しているかどうかは不明ですが、モデルのエンティティの多くは、共通フィールドを含むようにBaseEFクラスを継承しています。

モデルとCREATEDB両方利用EF 6.0.0.0:私はdevのデータベースを削除し、CREATEDBプログラムを実行する場合

(1)、私が手に:私は次のエラーを取得

<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, 
      Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> 

エラー、 "既にデータベースにアクティビティという名前のオブジェクトがあります"。

(2)プログラムでデータベースを削除できるようにすると、データベースをバックアップしているモデルが変更されたというエラーが表示されます。

私はモデルプロジェクトでマイグレーションを追加したり削除したりしてみました。

私は、次のプログラムを使用してのdevのデータベースを作成しています:

namespace AzureV1_CreateTestDB 
{ 
    class Program 
    { 
    static void Main(string[] args) 
    { 
     createDb(true); 
    } 

    public static void createDb(bool deleteDatabase) 
    { 
     IdentityEFContext dbContext = new IdentityEFContext(); 

     if (System.Configuration.ConfigurationManager.ConnectionStrings["IdentityEFContext"].ConnectionString.Contains("EFUpdatetest1")) 
     { 
     if (dbContext.Database.Exists()) 
     { 
      if (deleteDatabase) 
      { 
      // The following line throws this error: 
      // System.InvalidOperationException: 'The model backing the 'IdentityEFContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).' 

      dbContext.Database.ExecuteSqlCommand(TransactionalBehavior.DoNotEnsureTransaction 
      , string.Format("ALTER DATABASE {0} SET SINGLE_USER WITH ROLLBACK IMMEDIATE", dbContext.Database.Connection.Database)); 

      dbContext.Database.Delete(); 
      } 
     } 

     initDBContext(dbContext); 
     System.Data.Entity.Core.Objects.ObjectContext oContext = ((IObjectContextAdapter)dbContext).ObjectContext; 

     if (System.Configuration.ConfigurationManager.ConnectionStrings["IdentityEFContext"].ConnectionString.Contains("EFUpdatetest1")) 
     { 
      ExecuteSql(oContext, "ALTER DATABASE EFUpdatetest1 SET ALLOW_SNAPSHOT_ISOLATION ON"); 
      ExecuteSql(oContext, "ALTER DATABASE EFUpdatetest1 SET READ_COMMITTED_SNAPSHOT ON"); 
     } 

     // insert data 
     InsertData(dbContext); 

     closeDBContext(dbContext); 

     MessageBox.Show("Database successfully created"); 
     } 
    } 

    public static void initDBContext(IdentityEFContext dbContext) 
    { 
     // The following line throws the error: 
     // System.Data.SqlClient.SqlException: 'There is already an object named 'Activities' in the database.' 

     while (((IObjectContextAdapter)dbContext).ObjectContext.Connection.State.ToString() != "Open") 
     { 
     ((IObjectContextAdapter)dbContext).ObjectContext.Connection.Open(); 
     } 
    } 
    } 
} 
// connectionString in createDb 

<connectionStrings> 
    <add name="IdentityEFContext" 
     providerName="System.Data.SqlClient" 
     connectionString="Server=localhost; Integrated Security=False; Database=EFUpdatetest1; User Id=dbtest; Password=Hello.123" /> 
</connectionStrings> 

EFの構成情報は以下の通りです:

// EntityContext.cs

using Microsoft.AspNet.Identity.EntityFramework; 
using Models; 
using System.Data.Entity; 
using System.Data.Entity.Migrations; 

namespace DataAccess 
{ 
    //public class IdentityEFContext : DbContext /* this works */ 
    public class IdentityEFContext : IdentityDbContext<User> 
    { 
    public IdentityEFContext() : base("IdentityEFContext") { } 

    static IdentityEFContext() 
    { 
     Database.SetInitializer<IdentityEFContext>(new IdentityEFInit()); 
    } 

    public static IdentityEFContext Create() 
    { 
     return new IdentityEFContext(); 
    } 

    public DbSet<Activity> Activities { get; set; } 
    ... 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     base.OnModelCreating(modelBuilder); 

     modelBuilder.Configurations.Add(new ActivityConfig()); 
     ... 
    } 
    } 

    //public class IdentityEFInit : DropCreateDatabaseIfModelChanges<IdentityEFContext> 
    public class IdentityEFInit : CreateDatabaseIfNotExists<IdentityEFContext> 
    { 
    protected override void Seed(IdentityEFContext context) 
    { 
     PerformInitialSetup(context); 
     base.Seed(context); 
    } 

    public void PerformInitialSetup(IdentityEFContext context) 
    { 
     // initial configuration will go here 
    } 
    } 
} 

//エンティティの設定がされていますとして:

namespace DataAccess 
{ 
    public class BaseEfConfiguration<TEntity> : EntityTypeConfiguration<TEntity> 
    where TEntity : BaseEF 
    { 
    public BaseEfConfiguration() 
    { 
     Property(b => b.ServerVersion).IsOptional(); 
     ... 
    } 
    } 

    public class ActivityConfig : BaseEfConfiguration<Activity> 
    { 
    public ActivityConfig() 
     : base() 
    { 
     ToTable("Activities"); 
     Property(a => a.Name).IsRequired(); 
     HasRequired(a => a.CreatedBy).WithMany(u => u.ActivitiesCreated).WillCascadeOnDelete(false); 
     ... 
    } 
    } 
} 

// connectionstring in app.config 
<connectionStrings> 
    <add name="IdentityEFContext" 
     providerName="System.Data.SqlClient" 
     connectionString="Server=localhost; Integrated Security=False; Database=EFUpdateTest1_Azure; User Id=dbtest; Password=Hello.123" /> 
    </connectionStrings> 

Userクラスは次のとおりです。

public class User : IdentityUser 
{ 
    public string Alias { get; set; } 
    ... 
} 

答えて

0

私がモデルに変更を加えた後、テストデータベースを作成する前に、移行を追加していませんでした。エンティティモデルを含むプロジェクトで移行が有効になっている場合、モデルを使用してデータベースを作成するプロジェクトは、既存の移行情報を使用してEntityTypeConfiguration情報ではなくデータベースを作成することに気付きませんでした。

解決策は、モデルを更新した後で最初に移行を追加することでした。その後、通常どおりにテストデータベースを作成しようとします。

これは誰かにとって役に立ちます。

関連する問題