Как соединить 2 базы данных внутри одного цикла Foreach для нескольких строк данных без открытия и закрытия соединения каждый раз для каждой строки

У меня есть сценарий, в котором я буду получать данные с несколькими строками данных (иногда в тысячах), и мне нужно обрабатывать данные построчно. При обработке данных построчно сначала мне нужно вызвать базу данных ONprem sql, где я вызову хранимую процедуру с входными и выходными параметрами, и после выполнения SP мне нужно получить выходные данные и обновить другую таблицу, которая находится в другая база данных SQL Azure в соответствии с выходным параметром.

Проблема в том, что когда я использую USING, я чувствую, что он открывает и закрывает соединение один раз для каждой строки для каждой из двух баз данных, и если есть 1000 строк данных, он может открывать и закрывать DB1 10000 каждый и DB2 1000 каждый, который занимает много времени и обращений к серверу.

Как я могу свести к минимуму это и, возможно, оставить соединение открытым, пока оно не сделает все в цикле foreach.

Ниже приведен пример фрагмента кода:

public void Main()
{

    //Declare Variables
    int InputID;
    string OutputProcessedMsg;
    string SqlConn = "Data Source=xyx.com;Initial Catalog=ddddd;Provider=SQLNCLI11.1;Integrated Security=SSPI";
    string AzureSqlConn = "Data Source=vvvv.dev.com;Initial Catalog=yyyy;Provider=SQLNCLI11.1;Integrated Security=SSPI";
    Object AllData = Dts.Variables["User::VarAllPowerAppData"].Value;
    // this gets the data object and sets it to a data table
    OleDbDataAdapter A = new OleDbDataAdapter();
    System.Data.DataTable dt = new System.Data.DataTable();
    A.Fill(dt, AllData);
    //DataTable sourceTable = dt;

    foreach (DataRow dr in dt.Rows)
    {
        InputID = Convert.ToInt32(dr[0]);

        using (SqlConnection conn = new SqlConnection(SqlConn))
        {
            using (SqlCommand cmd = new SqlCommand("UpdateDataOnpremSQL", conn))
            {
                cmd.CommandType = CommandType.StoredProcedure;
                // set up the parameters and it's values
                cmd.Parameters.Add("@ID", SqlDbType.VarChar,15).Value = InputDealerID;
                cmd.Parameters.Add("@ProcessedMsg", SqlDbType.VarChar,-1).Direction = ParameterDirection.Output;
                conn.Open();
                cmd.ExecuteNonQuery();
                OutputProcessedMsg = Convert.ToString(cmd.Parameters["@ProcessedMsg"].Value);
                conn.Close();

            }
        }

        using (OleDbConnection Oconn = new OleDbConnection(AzureSqlConn))
        {
            using (OleDbCommand cmd = new OleDbCommand("UpdateDataAzureSQL", Oconn))
            {
                cmd.CommandType = CommandType.StoredProcedure;
                // set up the parameters and it's values
                cmd.Parameters.AddWithValue("@ID", SqlDbType.VarChar).Value = InputDealerID;
                cmd.Parameters.AddWithValue("@ProcessedMsg", SqlDbType.VarChar).Value = OutputProcessedMsg;
                Oconn.Open();
                cmd.ExecuteNonQuery();
                Oconn.Close();
            }
        }
    }
}

Я пробовал этот пул соединений, но кажется, что для каждой строки он попадет в db, откроет и закроет соединения, которые повлияют на производительность сервера БД, и, следовательно, мне нужно что-то, где соединение будет открыто, и процесс будет быстрее при переключении на БД до конца цикла foreach Databtable

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
121
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Он делает то, о чем вы его просите. Вы объявляете свои связи внутри цикла foreach. На каждой итерации он создает новое соединение, открывает его, выполняет команду и закрывает соединение.

Чтобы добиться лучшей производительности, вам следует подумать о создании соединения в вашем блоке Declare Variables, открыть его после создания, выполнить все команды в вашем цикле и закрыть соединение после завершения цикла.

Вы открываете соединение перед циклом

А потом закрыть их

public void Main()
{

    //Declare Variables
    int InputID;
    string OutputProcessedMsg;
    string SqlConn = "Data Source=xyx.com;Initial Catalog=ddddd;Provider=SQLNCLI11.1;Integrated Security=SSPI";
    SqlConnection conn = new SqlConnection(SqlConn);
    
    string AzureSqlConn = "Data Source=vvvv.dev.com;Initial Catalog=yyyy;Provider=SQLNCLI11.1;Integrated Security=SSPI";
    OleDbConnection Oconn = new OleDbConnection(AzureSqlConn);
    
    Object AllData = Dts.Variables["User::VarAllPowerAppData"].Value;
    // open all connections only once
    conn.Open();
    Oconn.Open();
    // this gets the data object and sets it to a data table
    OleDbDataAdapter A = new OleDbDataAdapter();
    System.Data.DataTable dt = new System.Data.DataTable();
    A.Fill(dt, AllData);
    //DataTable sourceTable = dt;

    foreach (DataRow dr in dt.Rows)
    {
        InputID = Convert.ToInt32(dr[0]);

        using (SqlCommand cmd = new SqlCommand("UpdateDataOnpremSQL", conn))
        {
            cmd.CommandType = CommandType.StoredProcedure;
            // set up the parameters and it's values
            cmd.Parameters.Add("@ID", SqlDbType.VarChar, 15).Value = InputID;
            cmd.Parameters.Add("@ProcessedMsg", SqlDbType.VarChar, -1).Direction = ParameterDirection.Output;
            
            cmd.ExecuteNonQuery();
            OutputProcessedMsg = (string)cmd.Parameters["@ProcessedMsg"].Value;


        }


        using (OleDbCommand cmd = new OleDbCommand("UpdateDataAzureSQL", Oconn))
        {
            cmd.CommandType = CommandType.StoredProcedure;
            // set up the parameters and it's values
            cmd.Parameters.AddWithValue("@ID", SqlDbType.VarChar).Value = InputID;
            cmd.Parameters.AddWithValue("@ProcessedMsg", SqlDbType.VarChar).Value = OutputProcessedMsg;
                
            cmd.ExecuteNonQuery();
                
        }
    }
    conn.Close();
    Oconn.Close();
}

Другие вопросы по теме