/// <summary> /// Helper function for generating the scripts for tables & constraints. /// </summary> /// <param name="itemCollection"> </param> /// <returns> </returns> internal static List<string> CreateObjectsScript(StoreItemCollection itemCollection, bool returnWarnings) { var builder = new SqlDdlBuilder(); // Iterate over the container. foreach (var container in itemCollection.GetItems<EntityContainer>()) { // Generate create table statements. foreach (var set in container.BaseEntitySets) { // If it is a type of entitySet, generate Create Table statements. var entitySet = set as EntitySet; if (entitySet != null) { builder.AppendCreateTable(entitySet); } } // Generate Foreign Key constraints. foreach (var set in container.BaseEntitySets) { // If it is association set, generate Foreign Key constraints. var associationSet = set as AssociationSet; if (associationSet != null) { builder.AppendCreateForeignKeys(associationSet); } } } // Return the final command text. return builder.GetCommandText(returnWarnings); }
protected override void DbCreateDatabase(DbConnection connection, int?timeOut, StoreItemCollection storeItemCollection) { Check.NotNull(connection, "connection"); Check.NotNull(storeItemCollection, "storeItemCollection"); // Validate that connection is a SqlCeConnection. ValidateConnection(connection); // We don't support create/delete database operations inside a transaction as they can't be rolled back. if (InTransactionScope()) { throw ADP1.CreateDatabaseNotAllowedWithinTransaction(); } if (_isLocalProvider) { var engine = new SqlCeEngine(DbInterception.Dispatch.Connection.GetConnectionString(connection, new DbInterceptionContext())); engine.CreateDatabase(); engine.Dispose(); } else { try { Type rdpType; // If we are working with RDP, then we will need to invoke the APIs through reflection. var engine = RemoteProviderHelper.GetRemoteSqlCeEngine( DbInterception.Dispatch.Connection.GetConnectionString(connection, new DbInterceptionContext()), out rdpType); Debug.Assert(engine != null); // Invoke the required method on SqlCeEngine. var mi = rdpType.GetMethod("CreateDatabase", new[] { typeof(int?) }); Debug.Assert(mi != null); // We will pass 'timeout' to RDP, this will be used as timeout period for connecting and executing on TDSServer. mi.Invoke(engine, new object[] { timeOut }); } catch (Exception e) { throw e.GetBaseException(); } } // Create the command object depending on provider. var command = connection.CreateCommand(); // Create the command texts from StoreItemCollection. var commandTextCollection = SqlDdlBuilder.CreateObjectsScript(storeItemCollection, false); DbTransaction transaction = null; var interceptionContext = new DbInterceptionContext(); try { // Open the connection. DbInterception.Dispatch.Connection.Open(connection, interceptionContext); // Open a transaction and attach to the command. transaction = DbInterception.Dispatch.Connection.BeginTransaction(connection, new BeginTransactionInterceptionContext()); command.Transaction = transaction; // Execute each statement. foreach (var text in commandTextCollection) { command.CommandText = text; DbInterception.Dispatch.Command.NonQuery(command, new DbCommandInterceptionContext()); } // Commit the transaction. DbInterception.Dispatch.Transaction.Commit(transaction, interceptionContext); } catch (Exception e) { if (transaction != null) { // Rollback the transaction. DbInterception.Dispatch.Transaction.Rollback(transaction, interceptionContext); } // Throw IOE with SqlCeException embedded as inner exception. throw new InvalidOperationException(EntityRes.GetString(EntityRes.IncompleteDatabaseCreation), e); } finally { // Close connection and cleanup objects. if (command != null) { command.Dispose(); } if (transaction != null) { DbInterception.Dispatch.Transaction.Dispose(transaction, interceptionContext); } if (connection != null) { DbInterception.Dispatch.Connection.Close(connection, interceptionContext); } } }