4

私はMVC 3のデプロイメントをAzureトライアルで行いたいと思っていますが、EF4.1データベースを作成することで壁に打たれたようです。SQLコードの最初のDB - ドロップ/作成ではなくテーブルを作成

実行している、それが正常に接続が、エラーを与える:

Invalid object name 'dbo.TableName'. 

私は、DBが存在するためであると考えているが、それにはテーブルがありません。私はローカルでそれを再現することができました - 私は私のSQL ExpressのDBを削除する場合は、DBのレクリエーションがうまく動作しますが、私はすべてのテーブルを削除し、DBを残してください。

私は、Global.asaxのに追加することができる方法をよく読んでました:

protected void Application_Start() 
{ 
    // Use any of: 
    System.Data.Entity.Database.SetInitializer<MyDatabaseContext>(new DropCreateDatabaseIfModelChanges<MyDatabaseContext>()); 
    System.Data.Entity.Database.SetInitializer<MyDatabaseContext>(new CreateDatabaseIfNotExists<MyDatabaseContext>()); 
    System.Data.Entity.Database.SetInitializer<MyDatabaseContext>(new DropCreateDatabaseAlways<MyDatabaseContext>()); 
} 

...動作するようには思えません。 EdmMetadataテーブルでモデルハッシュを取得しようとしていないということについてのエラーもあります。

EF4.1/Code Firstで既存のDBにDB構造を作成するにはどうすればよいですか? (そしてAzureで...)。または、SQL Management StudioからDBをスクリプト化し、それを宛先DBに対して実行する必要がありますか?

+0

の可能複製(のhttp:/ /stackoverflow.com/questions/7358673/recreate-entity-framework-tables-not-databases) –

答えて

1

異なるデータベースイニシャライザを作成する必要があります。これは、再作成するのではなくデータベースをクリーンアップするだけです。

ここでは

using System.Collections.ObjectModel; 
using System.Data.Entity; 
using System.Data.Entity.Design; 
using System.Data.Entity.Infrastructure; 
using System.Data.Metadata.Edm; 
using System.Data.Objects; 
using System.Globalization; 
using System.Linq; 
using System.Security.Cryptography; 
using System.Text; 
using System.Xml; 

namespace Infrastructure 
{ 
public partial class RecreateSchemaIfModelChanges<T> : IDatabaseInitializer<T> where T : DbContext 
{ 
    private EdmMetadata _edmMetaData; 

    private bool CompatibleWithModel(string modelHash, DbContext context, ObjectContext objectContext) 
    { 
     if (objectContext.ExecuteStoreQuery<int>("Select COUNT(*) \r\n    FROM INFORMATION_SCHEMA.TABLES T \r\n    Where T.TABLE_NAME = 'EdmMetaData'", new object[0]).FirstOrDefault<int>() == 1) 
     { 
      this._edmMetaData = context.Set<EdmMetadata>().FirstOrDefault<EdmMetadata>(); 
      if (this._edmMetaData != null) 
      { 
       return (modelHash == this._edmMetaData.ModelHash); 
      } 
     } 
     return false; 
    } 

    private static string ComputeSha256Hash(string input) 
    { 
     byte[] buffer = new SHA256Managed().ComputeHash(Encoding.ASCII.GetBytes(input)); 
     StringBuilder builder = new StringBuilder(buffer.Length * 2); 
     foreach (byte num in buffer) 
     { 
      builder.Append(num.ToString("X2", CultureInfo.InvariantCulture)); 
     } 
     return builder.ToString(); 
    } 

    private void CreateTables(ObjectContext objectContext) 
    { 
     string commandText = objectContext.CreateDatabaseScript(); 
     objectContext.ExecuteStoreCommand(commandText, new object[0]); 
    } 

    private string GetCsdlXmlString(ObjectContext context) 
    { 
     if (context != null) 
     { 
      ReadOnlyCollection<EntityContainer> items = context.MetadataWorkspace.GetItems<EntityContainer>(DataSpace.SSpace); 
      if (items != null) 
      { 
       EntityModelSchemaGenerator generator = new EntityModelSchemaGenerator(items.FirstOrDefault<EntityContainer>()); 
       StringBuilder output = new StringBuilder(); 
       XmlWriter writer = XmlWriter.Create(output); 
       generator.GenerateMetadata(); 
       generator.WriteModelSchema(writer); 
       writer.Flush(); 
       return output.ToString(); 
      } 
     } 
     return string.Empty; 
    } 

    private string GetModelHash(ObjectContext context) 
    { 
     return ComputeSha256Hash(this.GetCsdlXmlString(context)); 
    } 

    public void InitializeDatabase(T context) 
    { 
     ObjectContext objectContext = ((IObjectContextAdapter)context).ObjectContext; 
     string modelHash = this.GetModelHash(objectContext); 
     if (!this.CompatibleWithModel(modelHash, context, objectContext)) 
     { 
      this.DeleteExistingTables(objectContext); 
      this.CreateTables(objectContext); 
      this.SaveModelHashToDatabase(context, modelHash, objectContext); 
      this.Seed(context); 
     } 
    } 

    private void SaveModelHashToDatabase(T context, string modelHash, ObjectContext objectContext) 
    { 
     if (this._edmMetaData != null) 
     { 
      objectContext.Detach(this._edmMetaData); 
     } 
     this._edmMetaData = new EdmMetadata(); 
     context.Set<EdmMetadata>().Add(this._edmMetaData); 
     this._edmMetaData.ModelHash = modelHash; 
     context.SaveChanges(); 
    } 

    private void DeleteExistingTables(ObjectContext objectContext) 
    { 
     var dropConstraintsScript = 
      @"declare @cmd varchar(4000) 
declare cmds cursor for 
      select 'ALTER TABLE ' + so.TABLE_NAME + ' DROP CONSTRAINT ' +   
so.constraint_name from INFORMATION_SCHEMA.TABLE_CONSTRAINTS so order by 
so.CONSTRAINT_TYPE 
open cmds 
while 1=1 
    begin 
     fetch cmds into @cmd 
      if @@fetch_status != 0 break 
          print @cmd 
          exec(@cmd) 
    end 
close cmds 
      deallocate cmds"; 
     string dropTablesScript = 
      @"declare @cmd varchar(4000) 
declare cmds cursor for 
      Select 'drop table [' + Table_Name + ']' From INFORMATION_SCHEMA.TABLES 
open cmds 
while 1=1 
    begin 
     fetch cmds into @cmd 
      if @@fetch_status != 0 break 
          print @cmd 
          exec(@cmd) 
    end 
close cmds 
      deallocate cmds"; 
     objectContext.ExecuteStoreCommand(dropConstraintsScript); 
     objectContext.ExecuteStoreCommand(dropTablesScript); 
    } 

} 
} 
0

はEF6のために建設されたが、まだその問題のために良いDbInitializer:[?データベース、エンティティフレームワークテーブルではなく再作成]

using Microsoft.AspNet.Identity; 
using Microsoft.AspNet.Identity.EntityFramework; 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 

using System.Data.Entity.Migrations; 

namespace MyProject.Models 
{ 
public class MrSaleDbInitializer : 
    //System.Data.Entity.DropCreateDatabaseIfModelChanges<MrSaleDbContext> 
    System.Data.Entity.DropCreateDatabaseAlways<MrSaleDbContext> 
{ 

    /* 
    * Seed: Don't delete the current db, don't delete any tables, but clear all rows data in current 
    * db-tables, then seed the db with a new initial data. 
    * note: Won't clear any Migration like tables or any AspNet tables such as: __MigrationHistory, AspNetUsers, AspNetRoles. 
    */ 
    protected override void Seed(MrSaleDbContext context)   
    { 
     this.ClearDb(context); 
     this.SeedAfterClearingDb(context); 
     base.Seed(context);   
    } 


    private void ClearDb(MrSaleDbContext context) 
    { 
     //Optional: disable all foreign keys (db-schema will be loosed). 
     //context.Database.ExecuteSqlCommand("EXEC sp_MSforeachtable @command1 = 'ALTER TABLE ? NOCHECK CONSTRAINT all'"); 

     List<string> tableNames = context.Database.SqlQuery<string>("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME NOT LIKE '%Migration%' AND TABLE_NAME NOT LIKE 'AspNet%'").ToList(); 

     for (int i = 0; tableNames.Count > 0; i++) 
     { 
      try 
      { 
       //To delete all tables and not just clean them from data, replace "DELETE FROM {0}" in "DROP TABLE {0}": 
       context.Database.ExecuteSqlCommand(string.Format("DELETE FROM {0}", tableNames.ElementAt(i % tableNames.Count))); 

       tableNames.RemoveAt(i % tableNames.Count); 
       i = -1; //flag: a table was removed. in the next iteration i++ will be the 0 index. 
      } 
      catch (System.Data.SqlClient.SqlException e) // ignore errors as these are expected due to linked foreign key data  
      { 
       //throw new Exception("Unable to clear any relevant table in data-base (due to foriegn key constraint ?). See inner-exception for more details.", e); 
       if ((i % tableNames.Count) == (tableNames.Count - 1)) 
       { 
        //end of tables-list without any success to delete any table, then exit with exception: 
        throw new System.Data.DataException("Unable to clear all relevant tables in database (foriegn key constraint ?). See inner-exception for more details.", e); 
       } 

      } 

     } 

     context.SaveChanges(); 
    } 


    /* 
    * SeedAfterClearingDb: seed the data-base with initial date after database was created. 
    */ 
    public void SeedAfterClearingDb(MrSaleDbContext context) 
    { 
     //seed the data-base with initial date after database was created. 

     //then... 

     //update all posts and save changes: 

     context.SaveChanges(); 

    } 
} 

}