27 Stimmen

Entity Framework CTP 4 - Code First - Benutzerdefinierter Datenbank-Initialisierer

Ich möchte eine benutzerdefinierte Datenbankinitialisierungsstrategie implementieren, so dass ich das Datenbankschema generieren und auf eine EXISTIERENDE LEERE SQL-Datenbank mit einer bereitgestellten Benutzer-ID und einem Passwort anwenden kann.

Leider bieten die integrierten Strategien nicht das, wonach ich suche:

// The default strategy creates the DB only if it doesn't exist - but it does 
// exist so this does nothing
Database.SetInitializer(new CreateDatabaseOnlyIfNotExists<DataContext>());

// Drops and re-creates the database but then this breaks my security mapping and 
// only works if using a “Trusted" connection
Database.SetInitializer(new RecreateDatabaseIfModelChanges<DataContext>());

// Strategy for always recreating the DB every time the app is run. – no good for 
// what I want
Database.SetInitializer(new AlwaysRecreateDatabase<DataContext>());

Ich habe die folgenden ausgearbeitet, aber dies nicht die ModelHash erstellen, so dass ich nicht in der Lage bin, zu verwenden "context.Database.ModelMatchesDatabase()" um zu überprüfen, ob das Datenbankschema erstellt wurde und um mehrfache Initialisierungen zu verhindern:

public class Initializer : IDatabaseInitializer<DataContext>  
{ 
    Public void InitializeDatabase(DataContext context)  
    {       
         // this generates the SQL script from my POCO Classes
         var sql = context.ObjectContext.CreateDatabaseScript();

         // As expected - when run the second time it bombs out here with "there is already an
         // object named xxxxx in the database"
         context.ObjectContext.ExecuteStoreCommand(sql); 

         this.seed(context)
         context.SaveChanges();
    }
}  

Fragen:

Weiß jemand, wie ich den Modell-Hash abrufen/erstellen kann (der eine EdmMetadata-Entität ist)?

-Or-

Gibt es eine bessere Möglichkeit, dies generell mit dem Code First CTP zu tun?

24voto

Luhmann Punkte 3802

Ich bin auf das gleiche Problem gestoßen. Ich habe es nicht wirklich gelöst, aber ich habe es geschafft, eine kleine böse Umgehung zum Laufen zu bringen, so dass ich meine Lösung für AppHarbor bereitstellen kann ;)

Seine eine IDatabaseInitializer-Implementierung, die nicht die Datenbank löschen, aber nur nukes alle Beschränkungen und Tabellen, und dann verwendet die ObjectContext.CreateDatabaseScript()-Methode, um die Sql zu generieren, und dann führe ich es als ein Storecommand. Ähnlich wie bei der obigen Implementierung in der Frage.

Aber ich habe auch Funktionalität hinzugefügt, um einen Hash aus dem Modell zu erstellen und speichern Sie es in db, und wenn es wieder ausgeführt wird, prüft es, ob das aktuelle Modell-Hash mit dem einen i db übereinstimmt. Genau wie die echte Code-First-Implementierung.

Ich konnte nicht machen es mit dem Build in context.Database.CompatibleWithModel(true) arbeiten - aber dies sollte genauso gut funktionieren, und da es eine vorübergehende Umgehung es sollte in Ordnung sein.

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

namespace Devtalk
{
    public class DontDropDbJustCreateTablesIfModelChanged<T> : IDatabaseInitializer<T> where T : DbContext
    {
        private EdmMetadata _edmMetaData;

        public void InitializeDatabase(T context)
        {
            ObjectContext objectContext = ((IObjectContextAdapter)context).ObjectContext;
            string modelHash = GetModelHash(objectContext);

            if (CompatibleWithModel(modelHash, context, objectContext)) return;

            DeleteExistingTables(objectContext);
            CreateTables(objectContext);

            SaveModelHashToDatabase(context, modelHash, objectContext);
        }

        private void SaveModelHashToDatabase(T context, string modelHash, ObjectContext objectContext)
        {
            if (_edmMetaData != null) objectContext.Detach(_edmMetaData);

            _edmMetaData = new EdmMetadata();
            context.Set<EdmMetadata>().Add(_edmMetaData);

            _edmMetaData.ModelHash = modelHash;
            context.SaveChanges();
        }

        private void CreateTables(ObjectContext objectContext)
        {
            string dataBaseCreateScript = objectContext.CreateDatabaseScript();
            objectContext.ExecuteStoreCommand(dataBaseCreateScript);
        }

        private void DeleteExistingTables(ObjectContext objectContext)
        {
            objectContext.ExecuteStoreCommand(Dropallconstraintsscript);
            objectContext.ExecuteStoreCommand(Deletealltablesscript);
        }

        private string GetModelHash(ObjectContext context)
        {
            var csdlXmlString = GetCsdlXmlString(context).ToString();
            return ComputeSha256Hash(csdlXmlString);
        }

        private bool CompatibleWithModel(string modelHash, DbContext context, ObjectContext objectContext)
        {
            var isEdmMetaDataInStore = objectContext.ExecuteStoreQuery<int>(LookupEdmMetaDataTable).FirstOrDefault();
            if (isEdmMetaDataInStore == 1)
            {            
                _edmMetaData = context.Set<EdmMetadata>().FirstOrDefault();
                if (_edmMetaData != null)
                {
                    return modelHash == _edmMetaData.ModelHash;
                }
            }
            return false;
        }

        private string GetCsdlXmlString(ObjectContext context)
        {
            if (context != null)
            {
                var entityContainerList = context.MetadataWorkspace.GetItems<EntityContainer>(DataSpace.SSpace);
                if (entityContainerList != null)
                {
                    EntityContainer entityContainer = entityContainerList.FirstOrDefault();
                    var generator = new EntityModelSchemaGenerator(entityContainer);
                    var stringBuilder = new StringBuilder();
                    var xmlWRiter = XmlWriter.Create(stringBuilder);
                    generator.GenerateMetadata();
                    generator.WriteModelSchema(xmlWRiter);
                    xmlWRiter.Flush();
                    return stringBuilder.ToString();
                }
            }
            return string.Empty;
        }

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

        private const string Dropallconstraintsscript =
            @"select  
                'ALTER TABLE ' + so.table_name + ' DROP CONSTRAINT ' + so.constraint_name  
                from INFORMATION_SCHEMA.TABLE_CONSTRAINTS so";

        private const string Deletealltablesscript =
            @"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";

        private const string LookupEdmMetaDataTable =
            @"Select COUNT(*) 
              FROM INFORMATION_SCHEMA.TABLES T 
              Where T.TABLE_NAME = 'EdmMetaData'";
    }
}

7voto

Daniel Little Punkte 16296

Dies ist der einfachste Weg, um an EF-Code zuerst weiterlaufend AppHarbor !

Die Verwendung des EdmMetadata.TryGetModelHash(context) Funktion, um zu prüfen, ob das Modell nicht mit der Datenbank übereinstimmt und einen Fehler mit dem neuen Code anzuzeigen, der nach der Ausführung von Änderungsskripten verwendet werden muss.

PopulateOnly : Erstellt nur Objekte, wenn die Datenbank leer ist

Ich dachte, ich würde meine eigene Version des Initializers posten, die ich derzeit auf appharbor a eine bestehende Datenbank aufzufüllen . Es wird auch versucht, eine Datenbank zu erstellen, wenn diese nicht existiert und wirft, wenn eine Änderung festgestellt wird (leider noch keine automatische Aktualisierung). Ich hoffe, jemand findet es nützlich.

    using System;
    using System.Data.Entity;
    using System.Data.Entity.Infrastructure;
    using System.Data.Objects;
    using System.Transactions;

    namespace Deskspace.EntityFramework
    {

        /// <summary> A Database Initializer for appharbor </summary>
        /// <typeparam name="T">Code first context</typeparam>
        public class PopulateOnly<T> : IDatabaseInitializer<T> where T : DbContext
        {
            private EdmMetadata metadata;

            private enum Status
            {
                Compatable,
                Invalid,
                Missing
            }

            /// <summary> Initializer that supports creating or populating a missing or empty database </summary>
            /// <param name="context"> Context to create for </param>
            public void InitializeDatabase(T context)
            {
                // Get metadata hash
                string hash = EdmMetadata.TryGetModelHash(context);

                bool exists;
                using (new TransactionScope( TransactionScopeOption.Suppress )) {
                    exists = context.Database.Exists();
                }

                if (exists) {

                    ObjectContext objectContext = ((IObjectContextAdapter)context).ObjectContext;

                    var dbHash = GetHashFromDatabase( objectContext );

                    Status compatability = 
                            string.IsNullOrEmpty( dbHash )? 
                        Status.Missing : 
                            (dbHash != hash)? 
                        Status.Invalid :
                        Status.Compatable;

                    if (compatability == Status.Missing) {

                        // Drop all database objects
                        ClearDatabase( objectContext );

                        // Recreate database objects
                        CreateTables( objectContext );

                        // Save the new hash
                        SaveHash( objectContext,  hash );

                    } else if (compatability == Status.Invalid) {

                        throw new Exception( 
                            "EdmMetadata does not match, manually update the database, expected: " + 
                            Environment.NewLine + 
                            "<[(" + hash + ")}>"
                        );
                    }
                } else {
                    context.Database.Create();
                    context.SaveChanges();
                }
            }

            private void ClearDatabase(ObjectContext objectContext)
            {
                objectContext.ExecuteStoreCommand( DropAllObjects );
            }

            private void CreateTables(ObjectContext objectContext)
            {
                string dataBaseCreateScript = objectContext.CreateDatabaseScript();
                objectContext.ExecuteStoreCommand( dataBaseCreateScript );
            }

            private void SaveHash(ObjectContext objectContext, string hash)
            {
                objectContext.ExecuteStoreCommand( string.Format(UpdateEdmMetaDataTable, hash.Replace( "'", "''" )) );
            }

            private string GetHashFromDatabase(ObjectContext objectContext)
            {
                foreach (var item in objectContext.ExecuteStoreQuery<string>( GetEdmMetaDataTable )) {
                    return item;
                }

                return string.Empty;
            }

            private const string UpdateEdmMetaDataTable = @"
    Delete From EdmMetadata;
    Insert Into EdmMetadata (ModelHash) Values ('{0}');";

            private const string GetEdmMetaDataTable = @"
    If Exists (Select * From INFORMATION_SCHEMA.TABLES tables where tables.TABLE_NAME = 'EdmMetaData')
        Select Top 1 ModelHash From EdmMetadata;
    Else
        Select '';";

            private const string DropAllObjects = @"
    declare @n char(1)
    set @n = char(10)

    declare @stmt nvarchar(max)

    -- procedures
    select @stmt = isnull( @stmt + @n, '' ) +
        'drop procedure [' + name + ']'
    from sys.procedures

    -- check constraints
    select @stmt = isnull( @stmt + @n, '' ) +
        'alter table [' + object_name( parent_object_id ) + '] drop constraint [' + name + ']'
    from sys.check_constraints

    -- functions
    select @stmt = isnull( @stmt + @n, '' ) +
        'drop function [' + name + ']'
    from sys.objects
    where type in ( 'FN', 'IF', 'TF' )

    -- views
    select @stmt = isnull( @stmt + @n, '' ) +
        'drop view [' + name + ']'
    from sys.views

    -- foreign keys
    select @stmt = isnull( @stmt + @n, '' ) +
        'alter table [' + object_name( parent_object_id ) + '] drop constraint [' + name + ']'
    from sys.foreign_keys

    -- tables
    select @stmt = isnull( @stmt + @n, '' ) +
        'drop table [' + name + ']'
    from sys.tables

    -- user defined types
    select @stmt = isnull( @stmt + @n, '' ) +
        'drop type [' + name + ']'
    from sys.types
    where is_user_defined = 1

    exec sp_executesql @stmt";

        }
    }

5voto

Alex Punkte 1208

Um die Lösung von @Luhmann zu unterstützen, hier meine Lösung, aber leicht geändert, um die FK und PK richtig zu löschen.

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 SISQuote.Server.Persistence
{
    public class DontDropExistingDbCreateTablesIfModelChanged<T> : IDatabaseInitializer<T> where T : DbContext
    {
        private EdmMetadata edmMetaData;

        public bool TryInitializeDatabase(T context)
        {
            ObjectContext objectContext = ((IObjectContextAdapter)context).ObjectContext;
            string modelHash = GetModelHash(objectContext);

            if (CompatibleWithModel(modelHash, context, objectContext))
                return false;

            DeleteExistingTables(objectContext);
            CreateTables(objectContext);
            SaveModelHashToDatabase(context, modelHash, objectContext);

            return true;
        }

        public void InitializeDatabase(T context)
        {
            TryInitializeDatabase(context);
        }

        private void SaveModelHashToDatabase(T context, string modelHash, ObjectContext objectContext)
        {
            if (edmMetaData != null) 
                objectContext.Detach(edmMetaData);

            edmMetaData = new EdmMetadata();
            context.Set<EdmMetadata>().Add(edmMetaData);

            edmMetaData.ModelHash = modelHash;
            context.SaveChanges();
        }

        private void CreateTables(ObjectContext objectContext)
        {
            string dataBaseCreateScript = objectContext.CreateDatabaseScript();
            objectContext.ExecuteStoreCommand(dataBaseCreateScript);
        }

        private void DeleteExistingTables(ObjectContext objectContext)
        {
            objectContext.ExecuteStoreCommand(DeleteAllTablesScript);
        }

        private string GetModelHash(ObjectContext context)
        {
            var csdlXmlString = GetCsdlXmlString(context).ToString();
            return ComputeSha256Hash(csdlXmlString);
        }

        public bool CompatibleWithModel(DbContext context)
        {
            ObjectContext objectContext = ((IObjectContextAdapter)context).ObjectContext;
            return CompatibleWithModel(GetModelHash(objectContext), context, objectContext);
        }

        private bool CompatibleWithModel(string modelHash, DbContext context, ObjectContext objectContext)
        {
            var isEdmMetaDataInStore = objectContext.ExecuteStoreQuery<int>(LookupEdmMetaDataTable).FirstOrDefault();
            if (isEdmMetaDataInStore == 1)
            {
                edmMetaData = context.Set<EdmMetadata>().FirstOrDefault();
                if (edmMetaData != null)
                {
                    return modelHash == edmMetaData.ModelHash;
                }
            }
            return false;
        }

        private string GetCsdlXmlString(ObjectContext context)
        {
            if (context != null)
            {
                var entityContainerList = context.MetadataWorkspace.GetItems<EntityContainer>(DataSpace.SSpace);
                if (entityContainerList != null)
                {
                    EntityContainer entityContainer = entityContainerList.FirstOrDefault();
                    var generator = new EntityModelSchemaGenerator(entityContainer);
                    var stringBuilder = new StringBuilder();
                    var xmlWRiter = XmlWriter.Create(stringBuilder);
                    generator.GenerateMetadata();
                    generator.WriteModelSchema(xmlWRiter);
                    xmlWRiter.Flush();
                    return stringBuilder.ToString();
                }
            }
            return string.Empty;
        }

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

        private const string DeleteAllTablesScript =
            @"declare @cmd varchar(4000)

              DECLARE cmds0 CURSOR FOR 
              SELECT 'ALTER TABLE ' + TABLE_NAME + ' DROP CONSTRAINT ' + CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE = 'FOREIGN KEY'

              DECLARE cmds1 CURSOR FOR 
              SELECT 'ALTER TABLE ' + TABLE_NAME + ' DROP CONSTRAINT ' + CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS

              DECLARE cmds2 CURSOR FOR 
              SELECT 'TRUNCATE TABLE ' + TABLE_NAME FROM INFORMATION_SCHEMA.TABLES

              DECLARE cmds3 CURSOR FOR 
              SELECT 'DROP TABLE [' + TABLE_NAME + ']' FROM INFORMATION_SCHEMA.TABLES

              open cmds0
              while 1=1
              begin
                  fetch cmds0 into @cmd
                  if @@fetch_status != 0 break
                  print @cmd
                  exec(@cmd)
              end
              close cmds0
              deallocate cmds0

              open cmds1
              while 1=1
              begin
                  fetch cmds1 into @cmd
                  if @@fetch_status != 0 break
                  print @cmd
                  exec(@cmd)
              end
              close cmds1
              deallocate cmds1

              open cmds2
              while 1=1
              begin
                  fetch cmds2 into @cmd
                  if @@fetch_status != 0 break
                  print @cmd
                  exec(@cmd)
              end
              close cmds2
              deallocate cmds2

              open cmds3
              while 1=1
              begin
                  fetch cmds3 into @cmd
                  if @@fetch_status != 0 break
                  print @cmd
                  exec(@cmd)
              end
              close cmds3
              deallocate cmds3";

        private const string LookupEdmMetaDataTable =
            @"Select COUNT(*) 
              FROM INFORMATION_SCHEMA.TABLES T 
              Where T.TABLE_NAME = 'EdmMetaData'";
    }
}

4voto

Matt Johnson-Pint Punkte 212496

Ich habe einen etwas anderen Ansatz für dieses Problem gewählt. Dies scheint ein guter Ort zu sein, um die Ergebnisse mitzuteilen.

Ich möchte nur Tabellen erstellen, die nicht bereits in der Datenbank vorhanden sind. Dies hat den Vorteil, dass ich neue Tabellen einführen kann, ohne den Rest der Datenbank zu löschen.

Dies ist auch hilfreich, wenn Sie mehrere Datenkontexte in einer Vererbungskette haben. Zum Beispiel, wenn Sie Ihre Anwendung in verschiedene Baugruppen aufteilen. Sie könnten einen Datenkontext in einem "Kern"-Modul haben und ihn dann in einer anderen Assembly für Zusatzmodule vererben. Diese Konfiguration funktioniert gut, aber die eingebauten Drop/Create-Initialisierer mögen es nicht, weil sich der Modell-Hash ständig ändert. Durch die Überprüfung des Vorhandenseins der Tabelle dauert die Initialisierung etwas länger, aber man hat dann keines dieser Probleme.

Wie auch immer, hier ist der Code:

/// <summary>
/// Database Initializer to create tables only if they don't already exist.
/// It will never drop the database.  Does not check the model for compatibility.
/// </summary>
/// <typeparam name="TContext">The data context</typeparam>
public class CreateTablesOnlyIfTheyDontExist<TContext> : IDatabaseInitializer<TContext>
  where TContext : DataContext
{
  public void InitializeDatabase(TContext context)
  {
    using (new TransactionScope(TransactionScopeOption.Suppress))
    {
      // If the database doesn't exist at all then just create it like normal.
      if (!context.Database.Exists())
      {
        context.Database.Create();
        return;
      }

      // get the object context
      var objectContext = ((IObjectContextAdapter)context).ObjectContext;

      // get the database creation script
      var script = objectContext.CreateDatabaseScript();

      if (context.Database.Connection is SqlConnection)
      {
        // for SQL Server, we'll just alter the script

        // add existance checks to the table creation statements
        script = Regex.Replace(script,
          @"create table \[(\w+)\]\.\[(\w+)\]",
          "if not exists (select * from INFORMATION_SCHEMA.TABLES " +
          "where TABLE_SCHEMA='$1' and TABLE_NAME = '$2')\n$&");

        // add existance checks to the table constraint creation statements
        script = Regex.Replace(script,
          @"alter table \[(\w+)\]\.\[(\w+)\] add constraint \[(\w+)\]",
          "if not exists (select * from INFORMATION_SCHEMA.TABLE_CONSTRAINTS " +
          "where TABLE_SCHEMA='$1' and TABLE_NAME = '$2' " +
          "and CONSTRAINT_NAME = '$3')\n$&");

        // run the modified script
        objectContext.ExecuteStoreCommand(script);
      }
      else if (context.Database.Connection is SqlCeConnection)
      {
        // SQL CE doesn't let you use inline existance checks,
        // so we have to parse each statement out and check separately.

        var statements = script.Split(new[] { ";\r\n" },
                        StringSplitOptions.RemoveEmptyEntries);
        foreach (var statement in statements)
        {
          var quoteSplitStrings = statement.Split('"');
          if (statement.StartsWith("CREATE TABLE"))
          {
            // Create a table if it does not exist.
            var tableName = quoteSplitStrings[1];
            const string sql = 
              "SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES " +
              "WHERE TABLE_NAME='{0}'"
            var checkScript = string.Format(sql, tableName);
            if (objectContext.ExecuteStoreQuery<int>(checkScript).First() == 0)
              objectContext.ExecuteStoreCommand(statement);
          }
          else if (statement.Contains("ADD CONSTRAINT"))
          {
            // Add a table constraint if it does not exist.
            var tableName = quoteSplitStrings[1];
            var constraintName = quoteSplitStrings[3];
            const string sql = 
              "SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS " +
              "WHERE TABLE_NAME='{0}' AND CONSTRAINT_NAME='{1}'";
            var checkScript = string.Format(sql, tableName, constraintName);
            if (objectContext.ExecuteStoreQuery<int>(checkScript).First() == 0)
              objectContext.ExecuteStoreCommand(statement);
          }
          else
          {
            // Not sure what else it could be. Just run it.
            objectContext.ExecuteStoreCommand(statement);
          }
        }
      }
      else
      {
        throw new InvalidOperationException(
          "This initializer is only compatible with SQL Server or SQL Compact Edition"
          );
      }
    }
  }
}

1voto

Equinox2000 Punkte 576

Auch ich war auf der Suche nach einer guten Lösung, da godaddy das Löschen/Erstellen von Datenbanken nicht erlaubt und somit keine Tabellen erstellt werden. Da die neuere Version von Entity Framework EDMData überholt hat, habe ich Alex' Code geändert, um zu sehen, ob eine DropMeToRecreateDatabase-Tabelle existiert oder nicht, wenn sie nicht existiert, löscht sie alle Tabellen und erstellt neue Tabellen.

using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Objects;
using System.Linq;

namespace LadyTreble.DatabaseInitializer
{

    public class DontDropExistingDbCreateTablesIfTableDropped<T> : IDatabaseInitializer<T> where T : DbContext
    {
        public bool TryInitializeDatabase(T context)
        {
            var objectContext = ((IObjectContextAdapter)context).ObjectContext;
            if (objectContext.ExecuteStoreQuery<int>(GetTableCount).FirstOrDefault() == 0)
            {
                this.DeleteExistingTables(objectContext);
                this.CreateTables(objectContext);
            }
            return true;
        }

        public void InitializeDatabase(T context)
        {
            this.TryInitializeDatabase(context);
        }

        private void CreateTables(ObjectContext objectContext)
        {
            string dataBaseCreateScript = objectContext.CreateDatabaseScript();
            objectContext.ExecuteStoreCommand(dataBaseCreateScript);
        }

        private void DeleteExistingTables(ObjectContext objectContext)
        {

            objectContext.ExecuteStoreCommand(DeleteAllTablesScript);
        }

        private const string DeleteAllTablesScript =
            @"declare @cmd varchar(4000)

              DECLARE cmds0 CURSOR FOR 
              SELECT 'ALTER TABLE ' + TABLE_NAME + ' DROP CONSTRAINT ' + CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE = 'FOREIGN KEY'

              DECLARE cmds1 CURSOR FOR 
              SELECT 'ALTER TABLE ' + TABLE_NAME + ' DROP CONSTRAINT ' + CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS

              DECLARE cmds2 CURSOR FOR 
              SELECT 'TRUNCATE TABLE ' + TABLE_NAME FROM INFORMATION_SCHEMA.TABLES

              DECLARE cmds3 CURSOR FOR 
              SELECT 'DROP TABLE [' + TABLE_NAME + ']' FROM INFORMATION_SCHEMA.TABLES

              open cmds0
              while 1=1
              begin
                  fetch cmds0 into @cmd
                  if @@fetch_status != 0 break
                  print @cmd
                  exec(@cmd)
              end
              close cmds0
              deallocate cmds0

              open cmds1
              while 1=1
              begin
                  fetch cmds1 into @cmd
                  if @@fetch_status != 0 break
                  print @cmd
                  exec(@cmd)
              end
              close cmds1
              deallocate cmds1

              open cmds2
              while 1=1
              begin
                  fetch cmds2 into @cmd
                  if @@fetch_status != 0 break
                  print @cmd
                  exec(@cmd)
              end
              close cmds2
              deallocate cmds2

              open cmds3
              while 1=1
              begin
                  fetch cmds3 into @cmd
                  if @@fetch_status != 0 break
                  print @cmd
                  exec(@cmd)
              end
              close cmds3
              deallocate cmds3

             CREATE TABLE DropMeToRecreateDatabase(id int IDENTITY(1,1) NOT NULL)";

        private const string GetTableCount =
            @"SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES T WHERE T.TABLE_NAME = 'DropMeToRecreateDatabase'";
    }

}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X