private void CloseConnection(IDataLoadEventListener listener)
        {
            if (_isDisposed)
            {
                return;
            }

            _isDisposed = true;
            try
            {
                if (TableLoadInfo != null)
                {
                    TableLoadInfo.CloseAndArchive();
                }

                if (_copy != null)
                {
                    _copy.Dispose();
                }

                if (_recordsWritten == 0)
                {
                    listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Warning, "Warning, 0 records written by SqlBulkInsertDestination (" + _dbInfo.Server + "," + _dbInfo.GetRuntimeName() + ")"));
                }
            }
            catch (Exception e)
            {
                listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Warning, "Could not close connection to server", e));
            }

            listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, "SqlBulkCopy closed after writing " + _recordsWritten + " rows to the server.  Total time spent writing to server:" + _timer.Elapsed));
        }
        public void Dispose(IDataLoadEventListener listener, Exception pipelineFailureExceptionIfAny)
        {
            try
            {
                if (_managedConnection != null)
                {
                    //if there was an error
                    if (pipelineFailureExceptionIfAny != null)
                    {
                        _managedConnection.ManagedTransaction.AbandonAndCloseConnection();

                        listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, "Transaction rolled back sucessfully"));

                        if (_bulkcopy != null)
                        {
                            _bulkcopy.Dispose();
                        }
                    }
                    else
                    {
                        _managedConnection.ManagedTransaction.CommitAndCloseConnection();

                        if (_bulkcopy != null)
                        {
                            _bulkcopy.Dispose();
                        }

                        listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, "Transaction committed sucessfully"));
                    }
                }
            }
            catch (Exception e)
            {
                listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Error, "Commit failed on transaction (probably there was a previous error?)", e));
            }

            //if we have a primary key to create
            if (pipelineFailureExceptionIfAny == null && _primaryKey != null && _primaryKey.Any() && discoveredTable != null && discoveredTable.Exists())
            {
                //Find the columns in the destination
                var allColumns = discoveredTable.DiscoverColumns();

                //if there are not yet any primary keys
                if (allColumns.All(c => !c.IsPrimaryKey))
                {
                    //find the columns the user decorated in his DataTable
                    DiscoveredColumn[] pkColumnsToCreate = allColumns.Where(c => _primaryKey.Any(pk => pk.Equals(c.GetRuntimeName(), StringComparison.CurrentCultureIgnoreCase))).ToArray();

                    //make sure we found all of them
                    if (pkColumnsToCreate.Length != _primaryKey.Count)
                    {
                        throw new Exception("Could not find primary key column(s) " + string.Join(",", _primaryKey) + " in table " + discoveredTable);
                    }

                    //create the primary key to match user provided columns
                    discoveredTable.CreatePrimaryKey(AlterTimeout, pkColumnsToCreate);
                }
            }

            EndAuditIfExists();
        }