Example #1
0
        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);
                }
            }
        }