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; }
...
}