Ошибка строки подключения

I have seen a lot of the same error but in different situations. My particular error is thrown right at the first SqlConnection line. I have no compilation errors so why is it failing?

SqlConnection sqlConn = new SqlConnection(WebConfigurationManager.
    ConnectionStrings["DefaultConnection"].
    ConnectionString);
SqlCommand command = new SqlCommand("dbo.InsertRecord", sqlConn);

sqlConn.Open();

command.CommandType = CommandType.StoredProcedure;

command.Parameters.Add(new SqlParameter("@Date", txtDate.Text));
command.Parameters.Add(new SqlParameter("@Title", TitleTextBox.Text));
command.Parameters.Add(new SqlParameter("@FirstName", FirstName.Text));
command.Parameters.Add(new SqlParameter("@LastName", LastName.Text));
command.Parameters.Add(new SqlParameter("@Comments", Comments.Text));

command.ExecuteNonQuery();
sqlConn.Close();

WebConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString is the following string:

Data Source=(LocalDb)v11.0;
Initial Catalog=aspnet-WebActivityLog-20140806121543;Integrated Security=SSPI;
AttachDBFilename=|DataDirectory|C:Usersv667719DocumentsVisual Studio 2013ProjectsWebActivityLogWebActivityLogApp_DataRecords.mdf

(Just without the newlines. Those were added for formatting.)

title description keywords services ms.service ms.subservice ms.custom ms.devlang ms.topic author ms.author ms.reviewer ms.date ms.openlocfilehash ms.sourcegitcommit ms.translationtype ms.contentlocale ms.lasthandoff ms.locfileid

Устранение временных ошибок

Узнайте, как устранять, диагностировать и предотвращать ошибки подключения SQL или временные ошибки при подключении к базе данных SQL Azure, Управляемый экземпляр Azure SQL и Azure синапсе Analytics.

подключение sql,строка подключения,проблемы с подключением, временная ошибка,ошибка подключения

sql-database

sql-database

development

sqldbrb=1

troubleshooting

dalechen

ninarn

sstein, vanto

01/14/2020

9f2e755047910aefa89c2f187cda956aca608b98

867cb1b7a1f3a1f0b427282c648d411d0ca4f81f

MT

ru-RU

03/19/2021

99093763

Устранение временных ошибок подключения в базе данных SQL и Управляемый экземпляр SQL

[!INCLUDEappliesto-sqldb-sqlmi-asa]

В этой статье описывается, как предотвратить, диагностировать и устранить ошибки подключения и временные ошибки, возникающие при взаимодействии клиентского приложения с базой данных SQL Azure, Azure SQL Управляемый экземпляр и Azure синапсе Analytics. Узнайте, как настроить логику повторных попыток, создать строку подключения и настроить другие параметры подключения.

Временные ошибки (временные сбои)

Временные ошибки (или временные сбои) возникают из-за причин, которые вскоре устраняются автоматически. Иногда временная ошибка возникает потому, что система Azure быстро сменяет аппаратные ресурсы, чтобы лучше распределить нагрузку, связанную с разными рабочими нагрузками. Большинство этих событий перенастройки завершаются менее чем за 60 секунд. Во время этого периода перенастройки могут возникнуть проблемы с подключением к базе данных в базе данных SQL. Приложения, подключающиеся к базе данных, должны быть построены для ожидания этих временных ошибок. и предусматривать их обработку путем реализации логики повторных попыток в коде вместо вывода пользователю сообщений об ошибках приложения.

Если клиентская программа использует пакет ADO.NET, ваша программа получает исключение SqlException и таким образом узнает о временной ошибке.

Подключение и команда

Повторите попытку подключения к базе данных SQL и SQL Управляемый экземпляр или установите ее снова в зависимости от следующих действий.

  • Временная ошибка возникает при попытке подключения.

Через несколько секунд повторите попытку подключения.

  • Временная ошибка возникает во время выполнения команды запроса базы данных SQL и SQL Управляемый экземпляр

Не повторяйте команду сразу. Лучше заново установите подключение после небольшой задержки. Затем снова выполните команду.

Повтор логики для временных ошибок

Клиентские программы, в которых иногда происходят временные ошибки, являются более надежными, если используют логику повторных попыток. Когда программа взаимодействует с базой данных в базе данных SQL с помощью по промежуточного слоя стороннего производителя, спросите у поставщика, содержит ли по промежуточного слоя логику повторных попыток для временных ошибок.

Принципы повторных попыток

  • Если ошибка является временной, попробуйте установить соединение снова.
  • Не пытайтесь напрямую повторно использовать базу данных SQL или SELECT инструкцию sql управляемый экземпляр, которая завершилась сбоем с временной ошибкой. Установите новое подключение и повторите SELECT.
  • Когда база данных SQL или инструкция SQL Управляемый экземпляр UPDATE завершается с временной ошибкой, установите новое подключение, прежде чем повторять попытку обновления. Логика повторных попыток обеспечивает полноценное выполнение транзакции базы данных или откат всей транзакции.

Другие соображения по поводу повторных попыток

  • Пакетная программа, которая автоматически запускается после окончания рабочего дня и завершает свою работу до наступления утра, может выполнять повторные попытки с продолжительными интервалами.
  • Программа, использующая пользовательский интерфейс, должна учитывать, что человек не любит ждать очень долго. Это не значит, что нужно повторять попытку каждые несколько секунд, так как подобная политика может переполнить систему запросами.

Увеличение интервала между повторными попытками

Рекомендуется подождать 5 секунд, прежде чем выполнять первую повторную попытку. Повторная попытка после ожидания менее 5 секунд может привести к перегрузке облачной службы. Для каждой последующей повторной попытки ожидание должно увеличиваться экспоненциально, но не более чем до 60 секунд.

Обсуждение периода блокировки для клиентов, использующих ADO.NET, см. в разделе Организация пулов соединений (ADO.NET).

Вы также можете задать максимальное количество повторных попыток, которые программа должна выполнить перед автоматическим завершением работы.

Образцы кода с логикой повторных попыток

Образцы кода с логикой повторных попыток доступны по ссылкам:

  • Устойчивое подключение к Azure SQL с помощью ADO.NET
  • Устойчивое подключение к Azure SQL с помощью PHP

Тестирование логики повторных попыток

Чтобы протестировать логику повторных попыток, нужно имитировать или вызвать ошибку, которую можно исправить во время работы программы.

Тестирование с отключением от сети

Один из способов протестировать логику повторных попыток — это отключить клиентский компьютер от сети во время работы программы. Ошибка:

  • SqlException.Number = 11001
  • Сообщение: «Данный узел неизвестен.»

В рамках первой повторной попытки можно подключить клиентский компьютер к сети и попытаться подключиться.

Чтобы сделать это тестирование практичным, следует отключить компьютер от сети, прежде чем запускать программу. Программа распознает параметр среды выполнения, после чего делает следующее.

  • Временно добавляет 11001 в свой список ошибок, чтобы эта ошибка считалась временной.
  • Первый раз пытается подключиться как обычно.
  • После выявления ошибки удаляет 11001 из списка.
  • Выводит сообщение с просьбой подключить компьютер к сети.
  • Программа приостанавливает дальнейшее выполнение с помощью метода Console.ReadLine или диалогового окна с кнопкой «ОК». Клавишу ВВОД пользователю нужно нажимать после подключения компьютера к сети.
  • Попытаться подключиться еще раз. В этот раз попытка должна завершиться успехом.

Проверка путем неправильного написания имени пользователя при подключении

Программа может намеренно сделать опечатку в имени пользователя перед первой попыткой подключения. Ошибка:

  • SqlException.Number = 18456
  • Сообщение: «Ошибка входа пользователя WRONG_MyUserName.»

В рамках первой повторной попытки программа может исправить опечатку, а затем попытаться подключиться.

Чтобы сделать это тестирование практичным, программа должна распознать параметр времени выполнения и сделать следующее:

  • Временно добавить 18456 в свой список ошибок, чтобы эта ошибка считалась временной.
  • Добавить элемент WRONG_ к имени пользователя.
  • После выявления ошибки удалить 18456 из списка.
  • Удалить WRONG_ из имени пользователя.
  • Попытаться подключиться еще раз. В этот раз попытка должна завершиться успехом.

Параметры .NET SqlConnection для повторной попытки подключения

Если клиентская программа подключается к базе данных в базе данных SQL с помощью платформа .NET Framework класса System. Data. SqlClient. SqlConnection, используйте .NET 4.6.1 или более поздней версии (или .NET Core), чтобы можно было использовать функцию повторного подключения. Дополнительные сведения об этой функции см. в разделе свойство SqlConnection. ConnectionString.

При создании строки подключения для объекта SqlConnection нужно правильно настроить значения следующих параметров.

  • ConnectRetryCount:     значение по умолчанию — 1. Диапазон — от 0 до 255.
  • ConnectRetryInterval:     значение по умолчанию — 10 секунд. Диапазон — от 1 до 60.
  • Время ожидания подключения:     по умолчанию — 15 секунд. Диапазон — от 0 до 2147483647.

В частности, выбранные значения должны обеспечивать равенство Connection Timeout = ConnectRetryCount * ConnectionRetryIntervall.

Например, если количество попыток — 3, интервал между ними составляет 10 секунд, а время ожидания подключения только 29 секунд, то у системы не останется времени для последней (третьей) попытки подключения: 29 < 3 * 10.

Подключение и команда

Параметры ConnectRetryCount и ConnectRetryInterval позволяют объекту SqlConnection повторять операцию подключения, не извещая об этом программу и не вынуждая ее управлять этим процессом. Повторные попытки будут выполняться в следующих ситуациях:

  • Вызов метода SqlConnection. Open
  • SqlConnection.Exeвызов метода милые

Есть один важный нюанс. Если во время выполнения запроса возникает временная ошибка, объект SqlConnection не пытается подключиться еще раз. Как следствие, запрос повторно не выполняется. Но перед отправкой запроса для выполнения объект SqlConnection очень быстро проверит наличие соединения. Если эта быстрая проверка обнаружит проблемы с подключением, SqlConnection повторит операцию подключения. Если повторная попытка подключения завершится успешно, запрос отправится на выполнение.

Нужно ли сочетать ConnectRetryCount с логикой повторных попыток в приложении?

Предположим, что в вашем приложении реализована надежная настраиваемая логика повторных попыток. Допустим, приложение повторяет операцию подключения четыре раза. Если вы добавите в строку подключения значения ConnectRetryInterval и ConnectRetryCount = 3, общее количество повторных попыток составит 4 * 3 = 12. Вряд ли вам действительно нужно такое количество повторных попыток.

Подключения к базе данных в базе данных SQL

Подключение: строка подключения

Строка подключения, необходимая для подключения к базе данных, немного отличается от строки, используемой для подключения к SQL Server. Строку подключения для своей базы данных вы можете скопировать на портале Azure.

[!INCLUDE sql-database-include-connection-string-20-portalshots]

Подключение: IP-адрес

Необходимо настроить базу данных SQL для приема подключения с IP-адреса компьютера, на котором размещена клиентская программа. Чтобы настроить эту конфигурацию, измените параметры брандмауэра с помощью портала Azure.

Если не задать IP-адрес, произойдет сбой программы и отобразится сообщение об ошибке, содержащее необходимый IP-адрес.

[!INCLUDE sql-database-include-ip-address-22-portal]

Дополнительные сведения см. в разделе Настройка параметров брандмауэра в базе данных SQL.

Подключение: порты

Обычно нужно убедиться лишь в том, что на компьютере, на котором установлено клиентское приложение, для исходящей связи открыт порт 1433.

Например, если ваша клиентская программа размещена на компьютере Windows, можно использовать брандмауэр Windows на этом узле, чтобы открыть порт 1433.

  1. Откройте панель управления.
  2. Выберите все элементы панели управления > Брандмауэр Windows > Дополнительные параметры > правила для исходящих подключений > действия > новое правило.

Если клиентская программа находится на виртуальной машине Azure, см. статью Порты для ADO.NET 4.5, отличные от порта 1433.

Общие сведения о настройке портов и IP-адресов в базе данных см. в разделе брандмауэр базы данных SQL Azure.

Подключение: ADO.NET 4.6.2 или более поздней версии

Если для подключения к Базе данных SQL программа применяет классы ADO.NET, например System.Data.SqlClient.SqlConnection, мы рекомендуем использовать .NET Framework 4.6.2 или более позднюю версию.

Начиная с ADO.NET 4.6.2:

  • Попытка повторного открытия подключения для SQL Azure будет выполнена немедленно, что повышает производительность приложений с поддержкой облака.

Начиная с ADO.NET 4.6.1:

  • Предлагает повышенную надежность подключения к базам данных SQL с помощью метода SqlConnection.Open. В методе Open теперь реализованы лучшие механизмы повторных попыток при временных сбоях, в частности для некоторых ошибок, которые возникают при ожидании соединения.
  • Поддерживается работа с пулами подключений, а также эффективная проверка функционирования объекта соединения, который видит ваша программа.

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

Если вы используете пакет ADO.NET 4.0 или более раннюю версию, мы рекомендуем обновить его до последней версии. С августа 2018 года доступна версия ADO.NET 4.6.2.

Диагностика

Диагностика: проверяет, могут ли служебные программы подключаться

Если программе не удается подключиться к базе данных в базе данных SQL, то один из вариантов диагностики заключается в попытке подключиться с помощью служебной программы. В идеале служебная программа подключается с помощью библиотеки, которую использует ваша программа.

На компьютерах под управлением Windows можно использовать следующие служебные программы:

  • SQL Server Management Studio (ssms.exe) подключается с помощью ADO.NET.
  • sqlcmd.exe подключается с помощью ODBC.

После подключения программы проверьте, работает ли короткий SQL-запрос SELECT.

Диагностика: проверка открытых портов

Если есть подозрение, что попытки подключения не удались из-за проблем с портом, запустите на компьютере служебную программу, которая сообщает о конфигурациях порта.

На компьютерах Linux можно использовать следующие служебные программы:

  • netstat -nap
  • nmap -sS -O 127.0.0.1 — вместо указанного в примере IP-адреса укажите свой.

В Windows можно использовать служебную программу PortQry.exe. Ниже приведен пример выполнения, который запросил ситуацию с портами в базе данных SQL и был запущен на переносном компьютере:

[C:Usersjohndoe]
>> portqry.exe -n johndoesvr9.database.windows.net -p tcp -e 1433

Querying target system called: johndoesvr9.database.windows.net

Attempting to resolve name to IP address...
Name resolved to 23.100.117.95

querying...
TCP port 1433 (ms-sql-s service): LISTENING

[C:Usersjohndoe]
>>

Диагностика: внесение ошибок в журнал

Эпизодические неисправности иногда лучше всего диагностировать, выявляя общий шаблон за несколько дней или недель подряд.

Клиент может помочь в диагностике. Для этого ему следует вносить в журнал все ошибки, с которыми он сталкивается. У вас может получиться коррелировать записи журнала со сведениями об ошибках, которые база данных SQL вносит в журнал для внутренних целей.

Для облегчения ведения журналов можно использовать Enterprise Library 6 (EntLib60), где используются классы .NET. Дополнительные сведения см. в статье 5 — As Easy As Falling Off a Log: Using the Logging Application Block (5. Простой вариант: использование решения Logging Application Block).

Диагностика: проверка системных журналов на наличие ошибок

Ниже приведены некоторые Transact-SQL-инструкции SELECT, которые запрашивают в журналах сведения об ошибках и прочую информацию.

Запрос у журнала Описание
SELECT e.*
FROM sys.event_log AS e
WHERE e.database_name = 'myDbName'
AND e.event_category = 'connectivity'
AND 2 >= DateDiff
  (hour, e.end_time, GetUtcDate())
ORDER BY e.event_category,
  e.event_type, e.end_time;
В представлении sys.event_log приводятся сведения об отдельных событиях, включая те, которые могут привести к временным ошибкам или проблемам с подключением.

В идеале значения start_time или end_time можно сопоставить с временем возникновения ошибок в клиентской программе.

Для выполнения этого запроса необходимо подключиться к базе данных master.

SELECT c.*
FROM sys.database_connection_stats AS c
WHERE c.database_name = 'myDbName'
AND 24 >= DateDiff
  (hour, c.end_time, GetUtcDate())
ORDER BY c.end_time;
Представление sys.database_connection_stats отображает суммарное количество событий каждого типа, что также бывает полезно при дополнительной диагностике.

Для выполнения этого запроса необходимо подключиться к базе данных master.

Диагностика: поиск событий проблемы в журнале базы данных SQL

Искать записи о событиях проблемы можно в журнале базы данных SQL. Попробуйте выполнить в базе данных master такую Transact-SQL-инструкцию SELECT:

SELECT
   object_name
  ,CAST(f.event_data as XML).value
      ('(/event/@timestamp)[1]', 'datetime2')                      AS [timestamp]
  ,CAST(f.event_data as XML).value
      ('(/event/data[@name="error"]/value)[1]', 'int')             AS [error]
  ,CAST(f.event_data as XML).value
      ('(/event/data[@name="state"]/value)[1]', 'int')             AS [state]
  ,CAST(f.event_data as XML).value
      ('(/event/data[@name="is_success"]/value)[1]', 'bit')        AS [is_success]
  ,CAST(f.event_data as XML).value
      ('(/event/data[@name="database_name"]/value)[1]', 'sysname') AS [database_name]
FROM
  sys.fn_xe_telemetry_blob_target_read_file('el', null, null, null) AS f
WHERE
  object_name != 'login_event'  -- Login events are numerous.
  and
  '2015-06-21' < CAST(f.event_data as XML).value
        ('(/event/@timestamp)[1]', 'datetime2')
ORDER BY
  [timestamp] DESC
;

Несколько возвращенных строк из sys.fn_xe_telemetry_blob_target_read_file

В следующем примере показано, как может выглядеть возвращаемая строка. Отображаемые пустые значения могут не быть пустыми в других строках.

object_name                   timestamp                    error  state  is_success  database_name

database_xml_deadlock_report  2015-10-16 20:28:01.0090000  NULL   NULL   NULL        AdventureWorks

Enterprise Library 6

Enterprise Library 6 (EntLib60) — это платформа классов .NET, которая помогает реализовать надежные клиенты облачных служб, одна из которых является базой данных SQL. Дополнительные сведения обо всех полезных возможностях EntLib60 вы найдете в этой статье.

Одна из областей, в которой может помочь EntLib60, — логика повторных попыток для обработки временных ошибок. Дополнительные сведения см. в статье 4 — Perseverance, Secret of All Triumphs: Using the Transient Fault Handling Application Block (4. Настойчивость — секрет всех побед. Использование блока приложения для обработки временных ошибок).

[!NOTE]
Исходный код для EntLib60 доступен для открытого скачивания в Центре загрузки. Корпорация Майкрософт не планирует обновлять функции и менять характер обслуживания библиотеки EntLib.

Классы EntLib60 для временных ошибок и повторов

Следующие классы EntLib60 особенно полезны для логики повторных ошибок. Все эти классы входят в пространство имен Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling или во вложенные пространства.

В пространстве имен Microsoft. Practices. EnterpriseLibrary. TransientFaultHandling:

  • RetryPolicy ;
    • ExecuteAction ;
  • Класс exponentialbackoff;
  • SqlDatabaseTransientErrorDetectionStrategy ;
  • ReliableSqlConnection ;
    • ExecuteCommand ;

В пространстве имен Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.TestSupport:

  • AlwaysTransientErrorDetectionStrategy ;
  • NeverTransientErrorDetectionStrategy ;

Ниже приведены некоторые ссылки на сведения об EntLib60.

  • Бесплатная загрузка 2-го издания книги Руководство разработчика по Microsoft Enterprise Library.
  • Рекомендации: в статье Общие рекомендации по повторным попыткам содержится подробное обсуждение логики повторных попыток.
  • Загрузка на сайте NuGet компонента Enterprise Library 6.0: Transient Fault Handling application block

EntLib60: блок ведения журнала

  • Блок ведения журнала — это очень гибкое и настраиваемое решение, которое позволяет выполнять такие действия:
    • создавать и хранить сообщения журнала в разных расположениях;
    • классифицировать и фильтровать сообщения;
    • собирать контекстную информацию, полезную для отладки, трассировки, аудита и выполнения общих требований к ведению журнала.
  • Это решение извлекает функции ведения журнала из расположения журнала, что обеспечивает согласованность кода приложения независимо от расположения и типа хранилища журнала.

Дополнительные сведения см. в статье 5 — As Easy As Falling Off a Log: Using the Logging Application Block (5. Простой вариант: использование решения Logging Application Block).

Исходный код метода EntLib60 IsTransient

Ниже приведен исходный код (на языке C#) метода IsTransient из класса SqlDatabaseTransientErrorDetectionStrategy. Исходный код поясняет, какие ошибки считаются временными и приемлемыми для повторной попытки (версия за апрель 2013 г.).

public bool IsTransient(Exception ex)
{
  if (ex != null)
  {
    SqlException sqlException;
    if ((sqlException = ex as SqlException) != null)
    {
      // Enumerate through all errors found in the exception.
      foreach (SqlError err in sqlException.Errors)
      {
        switch (err.Number)
        {
            // SQL Error Code: 40501
            // The service is currently busy. Retry the request after 10 seconds.
            // Code: (reason code to be decoded).
          case ThrottlingCondition.ThrottlingErrorNumber:
            // Decode the reason code from the error message to
            // determine the grounds for throttling.
            var condition = ThrottlingCondition.FromError(err);

            // Attach the decoded values as additional attributes to
            // the original SQL exception.
            sqlException.Data[condition.ThrottlingMode.GetType().Name] =
              condition.ThrottlingMode.ToString();
            sqlException.Data[condition.GetType().Name] = condition;

            return true;

          case 10928:
          case 10929:
          case 10053:
          case 10054:
          case 10060:
          case 40197:
          case 40540:
          case 40613:
          case 40143:
          case 233:
          case 64:
            // DBNETLIB Error Code: 20
            // The instance of SQL Server you attempted to connect to
            // does not support encryption.
          case (int)ProcessNetLibErrorCode.EncryptionNotSupported:
            return true;
        }
      }
    }
    else if (ex is TimeoutException)
    {
      return true;
    }
    else
    {
      EntityException entityException;
      if ((entityException = ex as EntityException) != null)
      {
        return this.IsTransient(entityException.InnerException);
      }
    }
  }

  return false;
}

Дальнейшие действия

  • Библиотеки подключений для Базы данных SQL и SQL Server
  • Организация пулов соединений (ADO.NET)
  • Retrying — это лицензированная общая библиотека Apache 2.0 для повторных попыток, написанная на языке Python, которая позволяет легко добавить режим повтора куда угодно.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace WindowsFormsApplication2
{
    public partial class OutoutTable : Form
    {
        string strSQL, strOp;
        SqlConnectionStringBuilder bldr;
        SqlConnection cn;
        public OutoutTable()
        {
            InitializeComponent();
            bldr = new SqlConnectionStringBuilder();
            bldr.DataSource = @"(local)HERO";
            bldr.IntegratedSecurity = true;
            bldr.AttachDBFilename = @"D:ISITLa2DBLineageII.mdf";
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
 
            string nameTable = "";
            string strSQL;
            switch (comboBox.SelectedIndex)
            {
                case 0: nameTable = "monster"; break;
                case 1: nameTable = "location"; break;
                case 2: nameTable = "item_armor"; break;
                case 3: nameTable = "item_weapon"; break;
                case 4: nameTable = "item_resurce"; break;
                case 5: nameTable = "item_other"; break;
            }
            strSQL = "SELECT*FROM" + nameTable;
            using (cn = new SqlConnection(bldr.ConnectionString))
            {
 
                try
                {
                    cn.Open();
                    SqlCommand cmd = new SqlCommand(strSQL, cn);
                    SqlDataReader rdr = cmd.ExecuteReader();
 
                    DataTable t = new DataTable();
                    t.Load(rdr);
                    dataGridView1.DataSource = t.DefaultView;
                    cn.Close();
 
                }
                catch (SqlException ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
         
        }
 
        private void checkBox2_CheckedChanged(object sender, EventArgs e)
        {
 
        }
 
        private void dataGridView2_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
 
        }
 
        private void button2_Click(object sender, EventArgs e)
        {
            if (checkArmor.Checked == false || checkLocation.Checked == false)
                strOp = "OR";
            else strOp = "AND";
            strSQL = " select monster.name_monster as Name, location.name_location as Location, item_weapon.name_item_weapon as Weapon, item_armor.name_item_armor as Armor, item_resurce.name_item as resurce, item_other.name_item_other as Other_item from info_monster inner join monster on monster.id_monster= info_monster.id_monster inner join location on location.id_location=info_monster.id_location  inner join item_weapon on item_weapon.id_item_weapon=info_monster.id_item_weapon  inner join item_armor on item_armor.id_item_armor=info_monster.id_item_armor  inner join item_resurce on item_resurce.id_item =info_monster.id_item_resurce inner join item_other on item_other.id_item_other=info_monster.id_item_other WHERE Armor LIKE'" + textPoiiskArmor.Text + "%' " + strOp + "Location='" + textPoiskLocation + "'";
 
            if (checkLocation.Checked == true)
                strSQL = " select monster.name_monster as Name, location.name_location as Location, item_weapon.name_item_weapon as Weapon, item_armor.name_item_armor as Armor, item_resurce.name_item as resurce, item_other.name_item_other as Other_item from info_monster inner join monster on monster.id_monster= info_monster.id_monster inner join location on location.id_location=info_monster.id_location  inner join item_weapon on item_weapon.id_item_weapon=info_monster.id_item_weapon  inner join item_armor on item_armor.id_item_armor=info_monster.id_item_armor  inner join item_resurce on item_resurce.id_item =info_monster.id_item_resurce inner join item_other on item_other.id_item_other=info_monster.id_item_other WHERE Location='" + textPoiskLocation.Text + "'";
 
            using (cn = new SqlConnection(bldr.ConnectionString))
            {
                try
                {
                    cn.Open();
                    SqlCommand cmd = new SqlCommand(strSQL, cn);
                    SqlDataReader rdr = cmd.ExecuteReader();
 
                    DataTable t = new DataTable();
                    t.Load(rdr);
                    dataGridView2.DataSource = t.DefaultView;
                    cn.Close();
 
                }
                catch(SqlException ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }
 
        private void button3_Click(object sender, EventArgs e)
        {
            string strSQL2;
            strSQL2 = " select monster.name_monster as Name, location.name_location as Location, item_weapon.name_item_weapon as Weapon, item_armor.name_item_armor as Armor, item_resurce.name_item as resurce, item_other.name_item_other as Other_item from info_monster inner join monster on monster.id_monster= info_monster.id_monster inner join location on location.id_location=info_monster.id_location  inner join item_weapon on item_weapon.id_item_weapon=info_monster.id_item_weapon  inner join item_armor on item_armor.id_item_armor=info_monster.id_item_armor  inner join item_resurce on item_resurce.id_item =info_monster.id_item_resurce inner join item_other on item_other.id_item_other=info_monster.id_item_other ;";
            using (cn = new SqlConnection(bldr.ConnectionString))
            {
                try
                {
                    cn.Open();
                    SqlCommand cmd = new SqlCommand(strSQL2, cn);
                    SqlDataReader rdr = cmd.ExecuteReader();
 
                    DataTable x = new DataTable();
                    x.Load(rdr);
                    dataGridView3.DataSource = x.DefaultView;
 
                    cn.Close();
 
                }
                catch (SqlException ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }
 
    }
}

Приложение реализует паттерн MVC и работает с базой данных (MS SQL Server). Бизнес-логика реализована в отдельном проекте в виде библиотеки классов, там же находятся модель ADO.NET, методы для обращения к БД, строка подключения добавлена в параметры и прописана в app.config. Использовалась модель Database First.

При таком построении приложение не может сделать запрос к БД, появляется ошибка «Не удалось найти строку подключения с именем … в файле конфигурации приложения». Я так понимаю, что приложение ищет строку подключения в файле App.config проекта, где реализованы Controller и View. А там ее нет, т.к. она в проекте библиотеки классов, где реализована Model. Как правильно решить такую проблему?

#db2 #db2-luw #connection-string

#db2 #db2-luw #строка подключения

Вопрос:

Я переношу полноценное приложение framework на .NET Core. В рамках полной платформы он использовал следующую строку подключения к IBM .СЕТЕВОЙ соединитель для DB2:

 "Server=localhost:50000;Database=testdb;"
 

Затем присваивается код UserID и Password свойства из хранилища учетных данных.

Теперь, в разделе Core, с IBM .NET Core connector для DB2, в частности, версии 2.0.0.100 (долгосрочная поддержка, согласно IBM), эта строка подключения вызывает исключение при создании из нее построителя строки подключения:

 {System.ArgumentNullException: Value cannot be null.
   at System.Threading.Monitor.ReliableEnter(Object obj, Booleanamp; lockTaken)
   at IBM.Data.DB2.Core.DB2ConnPool.ReplaceConnStrPwd(String value, String newvalue, Boolean onlyPwd)
   at IBM.Data.DB2.Core.DB2Connection.RemoveConnectionStringPassword(String value, Boolean bMask)
   at IBM.Data.DB2.Core.DB2ConnectionStringBuilder..ctor(String connectionString)
 

Нет InnerException . Я предполагаю, что некоторые обязательные параметры строки подключения, о которых я не знаю, должны быть заполнены в Core, тогда как в full framework они были необязательными. Внимательное чтение документов IBM по DB2 connector Core не дало никаких упоминаний об изменениях строки подключения, если только я их не пропустил. В этом сообщении в блоге не упоминалось о таких критических изменениях.

Кто-нибудь знает об обязательных параметрах строки подключения, которые отсутствуют в моей строке подключения специально для .NET Core connector?

Обновить:

Если я создам строку подключения вручную, объединив исходную строку выше с UserID=MyUser;Password=MyPWD; , и открою соединение с базой данных, то DB2ConnectionStringBuilder она будет работать даже с исходной строкой выше. Я не могу понять это! Это не имеет никакого смысла. Вся цель конструктора строк подключения состоит в том, чтобы создавать строки подключения из параметров строго типизированным способом. Есть идеи?

Комментарии:

1. Вы уверены, что пароль имеет какое-то значение?

2. На этом этапе пароль не имеет значения, поскольку строка подключения назначается DB2ConnectionStringBuilder объекту, а не DB2Connection объекту. Заявленная цель DB2ConnectionStringBuilder — добавить что-то позже, включая идентификатор пользователя и пароль. Исключение возникает в c..tor.

3. Ну, ошибка показывает: at IBM.Data.DB2.Core.DB2ConnPool.ReplaceConnStrPwd(

4. И что это значит?

5. У меня такая же проблема. Для обхода я создал DB2ConnectionStringBuilder без параметра, затем установил свойство ConnectionString. Я не смог заставить конструктор с (string) работать. Установка свойства ConnectionString действительно сработала, но это не идеальное решение, меня интересуют ответы, которые это находит. (IBM.Data.DB.Provider v11.1.4040.4; .NET Frameworkv4.7.2)

Ответ №1:

Если вы используете amp; IBM.Data.DB2.Core (3.1) пакет nuget с подключением типа:

 server=my server;database=myDatabase;user id=myUser;password=MyPassword
 

Тогда OdbcConnectionStringBuilder будет достаточно (например):

 var db2Connection = "server=my server;database=myDatabase;user id=myUser;password=MyPassword";
var connectionBuilder = new OdbcConnectionStringBuilder(connection);
var Db2Connection = new Db2Connection(builder.ToString());
 

или что-то вроде этого:

 var password = builder["password"]?.ToString();
 

У меня это прекрасно работает

Понравилась статья? Поделить с друзьями:
  • Ошибка стиральной машины whirlpool f04
  • Ошибка строка шаблона содержит непарные кавычки
  • Ошибка стиральной машины samsung черный
  • Ошибка строка 0 синтаксическая ошибка xml
  • Ошибка строительства квартиры симс 2