/// <summary>
        /// if bulkcopy failed,  rollback and then use table value SP. if transaction commit success then delete files
        /// </summary>
        private bool SaveDatabaseBatch(DatabaseBatch databaseBatch)
        {
            bool isSavedSuccess = true;
            try
            {
                using (SqlConnection sqlConnection = new SqlConnection(this._QuotationConnectionString))
                {
                    sqlConnection.Open();

                    using (SqlTransaction sqlTransaction = sqlConnection.BeginTransaction())
                    {

                        foreach (KeyValuePair<int, DataTable> keyValue in databaseBatch.OriginDataTables)
                        {
                            if (!SaveByBulkCopy(sqlConnection, sqlTransaction, keyValue.Value, keyValue.Key, true))
                            {
                                if (!SaveByTableValue(sqlConnection, sqlTransaction, keyValue.Value, keyValue.Key, true))
                                {
                                    isSavedSuccess = false;
                                    break;
                                }

                            }
                        }

                        foreach (KeyValuePair<int, DataTable> keyValue in databaseBatch.OverridedDataTables)
                        {
                            if (!SaveByBulkCopy(sqlConnection, sqlTransaction, keyValue.Value, keyValue.Key, false))
                            {
                                if (!SaveByTableValue(sqlConnection, sqlTransaction, keyValue.Value, keyValue.Key, false))
                                {
                                    isSavedSuccess = false;
                                    break;
                                }
                            }
                        }

                        if (isSavedSuccess)
                        {
                            SqlCommand sqlCommand = sqlConnection.CreateCommand();
                            sqlCommand.Transaction = sqlTransaction;
                            sqlCommand.CommandText = "dbo.P_UpdateLastSessionLastQuotation";
                            sqlCommand.CommandType = CommandType.StoredProcedure;
                            SqlParameter parameter = sqlCommand.Parameters.AddWithValue("@OriginQuotationTable", databaseBatch.LastSessionLastOriginQuotationTable);
                            parameter.SqlDbType = SqlDbType.Structured;
                            parameter = sqlCommand.Parameters.AddWithValue("@OverridedQuotationTable", databaseBatch.LastSessionLastOverridedQuotationTable);
                            parameter.SqlDbType = SqlDbType.Structured;

                            parameter = sqlCommand.Parameters.AddWithValue("@result", null);
                            parameter.Direction = ParameterDirection.ReturnValue;
                            sqlCommand.ExecuteNonQuery();

                            isSavedSuccess = (parameter.Value != DBNull.Value && (int)parameter.Value == 0);
                        }
                        if (isSavedSuccess)
                        {
                            sqlTransaction.Commit();
                        }
                        else
                        {
                            sqlTransaction.Rollback();
                        }
                    }
                }
            }
            catch (Exception exception)
            {

                AppDebug.LogEvent("QuotationServer", string.Format("QuotationFileCache.SaveDatabaseBatch error: {0}, {1}", string.Join(",", databaseBatch.FileNames), exception), EventLogEntryType.Error);
                return false;
            }

            if (isSavedSuccess)
            {
                foreach (string fileName in databaseBatch.FileNames)
                {
                    try
                    {
                        File.Delete(fileName);
                    }
                    catch (Exception exception)
                    {
                        //isSavedSuccess = false;
                        AppDebug.LogEvent("QuotationServer", string.Format("DatabaseBatch.SaveToDatabaseInternal warning: {0}", exception), EventLogEntryType.Warning);
                    }
                }
            }
            return isSavedSuccess;
        }
        ///////////////////////////////////////////////////
        //save memory quotations to database
        ///////////////////////////////////////////////////
        public bool SaveMemoryToDatabase()
        {
            try
            {
                //AppDebug.LogEvent("QuotationServer", string.Format("begin QuotationFileCache.SaveMemoryToDatabase, Queue.Count={0}", this._Queue.Count), EventLogEntryType.Information);
                lock (this._QueueLock)
                {
                    while (this._Queue.Count > 0)
                    {
                        MemoryBatch memoryBatch = this._Queue.Peek();
                        DatabaseBatch databaseBatch = new DatabaseBatch(memoryBatch);

                        if (this.SaveDatabaseBatch(databaseBatch))
                        {
                            databaseBatch.Clear();
                            this._Queue.Dequeue();
                        }

                        if (this._Queue.Count == 0 && this._ActiveMemoryBatch != null)
                        {
                            this._ActiveMemoryBatch = null;
                        }
                    }
                }
                //AppDebug.LogEvent("QuotationServer", string.Format("end QuotationFileCache.SaveMemoryToDatabase, Queue.Count={0}", this._Queue.Count), EventLogEntryType.Information);
                return true;
            }
            catch (Exception exception)
            {
                AppDebug.LogEvent("QuotationServer", string.Format("QuotationFileCache.SaveMemoryToDatabase error: {0}", exception), EventLogEntryType.Error);
                return false;
            }
        }