ASP.NET SQL подключение через ADO.NET
ADO.NET — это базовая технология доступа к данным. Основной целью технологии является снижение объемов кодирования и обслуживания. ADO.NET предоставляет самый прямой способ доступа к источникам данным MS SQL Server. Веб приложения ASP.NET используют возможности ADO.NET для соединения базами: для получения, обработки и обновления имеющихся в них данных.
Драйверы доступа к базам MS SQL Server
Сайты, построенные на платформе ASP.NET имеют возможность выбора нескольких драйверов (способов) работы с базой данных SQL Server посредством технологии ADO.NET. Для этого используются драйверы для объектно-реляционного сопоставления и драйверы объектно-реляционного доступа.
Драйверы объектно-реляционного сопоставления возвращают данные таблиц базы данных в виде экземпляров классов и их свойств. Примером драйверов объектно-ориентированного доступа к базам данных являются Entity Framework и Entity Framework Core.
Классические драйверы SQL для реляционного доступа используют SQL-язык для выполнения команд получения и обновления данных таблиц базы. Примером таких модулей являются System.Data.SqlClient и Microsoft.Data.SqlClient (введение в новый Microsoft.Data.SqlClient ➹).
Поставщик данных Microsoft.Data.SqlClient создан для .NET Framework, .NET Core и .NET Standard с перспективой долгосрочной поддержки. Модуль Microsoft.Data.SqlClient можно установить через диспетчера пакетов NuGet. В конце статьи прикреплен исходник использования данного модуля доступа к данным.
База данных исходника
Получение данных из базы MS SQL
- Подготовка подключения к базе. Выбор способа подключения и создание строки подключения.
- Создание команды получения или обновления данных. SQL команды (запросы) создаются посредством объектов класса SQLCommand.
- Подключение к базе данных и выполнение команд (SQL запросов). Подключение происходит через объект SQLConnection.
- Получение данных. Если выполняется команда SELECT, то ожидается возврат данных в виде таблиц. Получить данные помогают объекты классов SQLDataAdapter и SQLDataReader.
Примеры строк подключения к MS SQL Server
Формирование подключения начинается с создания строки подключения. Строка подключения для SQL представляет собой входную текстовую информацию с указанием имени сервера, названия базы данных, способа проверки подлинности, идентификационные данные пользователя и некоторую служебную информацию.
Пример строки подключения. Проверка подлинности SQL Server:
«Data Source=COMPSQLEXPRESS_2016;Initial Catalog=DBMSSQL;Persist Security Info=False;Integrated Security=False;User > COMPSQLEXPRESS_2016 — имя сервера DBMSSQL — название базы данных Persist Security Info=False — запрет сохранения идентификационных данных после открытия соединения. Integrated Security=False — проверка подлинности пользователя SQL сервером pashaSQL2016;Password=1234 — регистрационные данные пользователя на SQL сервере Пример строки подключения. Проверка подлинности Windows:
Data Source=COMPSQLEXPRESS_2016;Initial Catalog=DBMSSQL;Integrated Security=True COMPSQLEXPRESS_2016 — имя сервера DBMSSQL — название базы данных Integrated Security=True — проверка подлинности пользователя зарегистрированного в OS Windows
Подключение к SQL Server
Соединение с базой данных MS SQL Server происходит при помощи экземпляра класса SQLConnection. Завершая сеанс связи с сервером баз данных необходимо явно закрывать соединение вызывая методы Close() или Dispose() .
Объект SqlConnection выходя за пределы области видимости не закрывается самостоятельно. Для гарантированного автоматического закрытия соединения рекомендуется использовать оператор using .
Листинг метода подключения и выполнения запросов к базе данных:
public static List CreateQuerySqlSeveralTables(string queryString, bool pooling=true) < ListlistTables = new(); // C# 9.0 string connectionString = Constants.SqlConnectionIntegratedSecurityPooling; if (pooling == false) connectionString = Constants.SqlConnectionIntegratedSecurityNoPooling; using SqlConnection connection = new(connectionString); // C# 9.0 using SqlCommand command = new(queryString, connection); // C# 9.0 connection.Open(); using SqlDataReader reader = command.ExecuteReader(CommandBehavior.KeyInfo); while (reader.IsClosed == false) < DataTable result = new(); // C# 9.0 result.Load(reader); listTables.Add(result); >return listTables; >
Строка подключения к MS SQL Server создана с помощью построителя, объекта класса SqlConnectionStringBuilder входящего в состав пространства имён Microsoft.Data.SqlClient. Таким способом создаётся синтактически правильная строка подключения к серверу базы данных. Подробнее о создании строки подключения к серверу баз данных можно прочитать в статье о взаимодействии с базой данных через модуль Entity Framework Core.
Объединение подключений — Pooling
Процесс подключения к SQL серверу состоит из нескольких последовательных шагов (установка сетевого соединения, анализ строки подключения, проверка идентификационных данных и др.), каждый из которых занимает некоторое время. При выполнении большого количества запросов к серверу базы данных, общее увеличение времени подключения перед запросами становится заметным и отражается на производительности веб приложения.
Для оптимизации подключений к базе данных технология ADO.NET генерирует пулы соединений. Пул в программировании — это набор ресурсов первоначально сформированных и хранящихся готовыми к использованию. При первом подключении создаётся готовая конфигурация соединения с сервером. После закрытия активного соединения объект подключения не уничтожается, а помещается в пул. При следующем подключении к серверу базы данных используется уже готовое соединение хранящееся в пуле. ADO.NET может создавать несколько пулов. В каждом пуле, в состоянии ожидания, могут храниться несколько десятков неактивных сформированных соединений. В одном пуле могут хранится только одинаковые соединения, имеющие идентичные строки подключения.
В ADO.NET по умолчанию включена поддержка пулов соединений. Если по каким-либо причинам понадобится отключить создание пулов, это можно сделать в строке подключения ключевым словом Pooling со значением False.
Например: «Data Source=PAVELSQLEXPRESS_2016;Initial Catalog=DBMSSQL;Integrated Security=True;Pooling=False»
Pooling — сравнение производительности
Для сравнения скорости обработки SQL запросов создадим два одинаковых кода запросов, с оптимизацией подключений и без неё. Две строки запроса к базе: в первой получение данных из одной таблицы, во второй одновременное выполнение сложной команды чтения данных. Для повышения точности измерения каждая команда повторяется установленное количество раз.
Одиночная команда, запрос к одной таблице: строка команды = «SELECT * FROM Sciences»;
Сложная команда, запрос данных в одной строке из нескольких таблиц: строка команды = («SELECT * FROM Sciences;SELECT * FROM Sections;SELECT * FROM SubSections; . . . SELECT * FROM TableN»);
Программный код множественных запросов к базе данных с созданием пулов и без использования оптимизации:
public IActionResult Index() < // Одиночная команда чтения. string queryString1 = "SELECT * FROM Sciences"; // --- Формирование сложной команды --- string queryString3 = null; int sizeQueryString3 = 10; for (int i = 0; i < sizeQueryString3; i++) < queryString3 += "SELECT * FROM Sciences;" + "SELECT * FROM Sections;" + "SELECT * FROM SubSections;"; >ViewBag.SizeQueryString3 = sizeQueryString3; // Количество повторений команд. int numRepeat = 100; ViewBag.NumRepeat = numRepeat; List dataTables = null; // --- Запросы с созданием пулов соединений --- DateTime dtPooling1 = DateTime.Now; for (int i = 0; i < numRepeat; i++) < dataTables = SqlQueries.CreateQuerySqlSeveralTables(queryString1); >ViewBag.PerfomancePooling1 = (DateTime.Now - dtPooling1).TotalMilliseconds; DateTime dtPooling3 = DateTime.Now; for (int i = 0; i < numRepeat; i++) < dataTables = SqlQueries.CreateQuerySqlSeveralTables(queryString3); >ViewBag.PerfomancePooling3 = (DateTime.Now - dtPooling3).TotalMilliseconds; // --- Запросы без создания пулов соединений --- DateTime dt1 = DateTime.Now; for (int i = 0; i < numRepeat; i++) < dataTables = SqlQueries.CreateQuerySqlSeveralTables(queryString1, false); >ViewBag.Perfomance1 = (DateTime.Now - dt1).TotalMilliseconds; DateTime dt3 = DateTime.Now; for (int i = 0; i < numRepeat; i++) < dataTables = SqlQueries.CreateQuerySqlSeveralTables(queryString3, false); >ViewBag.Perfomance3 = (DateTime.Now - dt3).TotalMilliseconds; return View(dataTables); >
Быстродействие SQLDataReader
Сравнительный тест быстродействия двух вариантов команд с включенным и отключенным пулингом соединений. В первом варианте выполняется команда запроса к одной таблице с повтором 100 раз. Во втором варианте выполняется команда запроса данных у 30 таблиц одновременно, также с повтором 100 раз.
Первое подключение к базе данных:
При первом соединении с базой данных одиночная команда с пулингом выполняется почти в 2 раза дольше, чем с отключёнными пулами. Сложные команды выполняются практически одинаковое время. Логично предположить, что дополнительное время затрачивается на создание пула.
Последующие запросы к базе данных:
Последующие запросы показывают эффективность «пуловой» оптимизации подключений технологии ADO.NET. Одиночные команды выполняются почти в 8 раз быстрее при использовании пулов подключений. В случае со сложными командами эффект использования оптимизации снижается, но всё равно без пулов запросы выполняются медленнее в 1,73 раза.
Быстродействие SQLDataAdapter
Первое подключение к базе данных:
Первое чтение из базы данных с помощью SQLDataAdapter происходит практически аналогично ситуации с SQLDataReader. Но комплексные команды, при включенном пулинге выполняются гораздо быстрее.
Последующие запросы к базе данных:
Последующие запросы одиночных команды выполняются почти в 14 раз быстрее при использовании пулов подключений. Сложные запросы выполняются также чувствительно быстрее с пулингом: в 2,6 раз быстрее подключений без оптимизации. Можно отметить, что SQLDataAdapter обеспечивает гораздо большую скорость выполнения запросов по сравнению с функциональностью SQLDataReader.
Инструменты для работы с исходниками
- Сервер баз данных — MS SQL Server, MS SQL Server Express или в крайнем случае можно использовать локальный сервер MSSQLLocalDB, идущий в составе Visual Studio).
- MS SQL Server Management Studio для создания и редактирования таблиц.
- Среда программирования MS Visual Studio 2019
Прикреплённые исходники
К статье прикреплены исходники сайта с подключением к базе данных MS SQL Server через технологию ADO.NET и непосредственно файл базы данных DBMSSQL. В исходниках простейший пример чтения данных из базы объектами чтения и обновления SQLDataReader и SQLDataAdapter. Сравнение скорости работы объектов при запросах к базе данных с оптимизацией и без.
Скачать исходник
Тема: «ASP.NET SQL подключение через ADO.NET»
aspsqladonet.zip Размер: 1470 Кбайт Загрузки: 295
Количество строк в результате запроса
В php, например, такое можно реализовать с помощью mysql_num_row, а как то же самое сделать в c#? Всем большое спасибо за помощь!
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
Количество элементов в результате запроса
сделал простенький запрос на вывод полей где есть определенное значение, а как сделать подсчет.
Запрос к базе Access с параметрами. Нет строк в результате запроса
string connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Data.mdb"; OleDbConnection.
Определить количество строк, полученных в результате SQL запроса
Здравствуйте! Вопрос такой: мне нужно узнать количество строк, полученных в результате SQL.
Объединение строк в результате запроса
Добрый день, форумчане! Тешу надеждой, что сможете момочь в одной проблемке. Есть запрос на вывод.
784 / 615 / 273
Регистрация: 04.08.2015
Сообщений: 1,707
DataReader не имеет свойства, возвращающего кол-во записей. Решений может быть несколько.
1. Загрузить данные в DataTable
1 2 3
DataTable dt = new DataTable(); dt.Load(reader); int numberOfResults = dt.DataRows.Count;
2. Подсчитывать кол-во строк в цикле прохода по DataReader.
3. Выполнить предварительно запрос, получающий кол-во строк.
1 2 3
using (MySqlCommand cmd = new MySqlCommand("select count(*) from news WHERE writeDate = '"+datepost+ "' AND writeTime > '"+timepost+"'"; SELECT header, date, message, user, writeDate, writeTime FROM "+ news WHERE writeDate = '"+datepost+"' AND writeTime > '"+timepost+"'", con))
Как соединить 2 запроса SQL
Как объединить два SQL запроса в один?
Хочу,чтобы при добавлении договора в COMBOBOX отображались заявки,поступившие от администрации. .
Как поместить результат sql-запроса в List<>?
Мне нужно поместить SELECT * FROM в список List, чтобы потом с ним работать, в таблице два.
Как редактировать данные в БД с помощью SQL запроса
public void RedDolj(string NazDolj)// метод редактирования ДОЛЖНОСТИ < .
Как передать результат sql-запроса в List<>?
SELECT * FROM Напишите пожалуйста как это реализовать. Если можно на примере.
Как поместить результат sql запроса в переменную?
sqlConnection = new SqlConnection(@"Data Source=DESKTOP-Q7TEGKR;Integrated Security=True;Connect.
Администратор
16392 / 12871 / 5072
Регистрация: 17.03.2014
Сообщений: 26,183
Записей в блоге: 1
Сообщение было отмечено Lyuniks как решение
Решение
Lyuniks, для этого не нужен второй запрос.
int rowCount = ds.Tables[0].Rows.Count;
P.S. Почему вы не используете параметры?
1 2 3 4 5 6 7 8 9 10 11 12 13 14
private void button1_Click(object sender, EventArgs e) { const string commandText = "SELECT * FROM Vhod WHERE [Рег_дата] > @ds AND [Рег_дата] < @de AND [Рег_дата] >@ds AND [Рег_дата] < @de"; const string connectionString = @"Data Source=DESKTOP-7CBKH8O\SQLEXPRESS;Initial Catalog=Lyuniks;Integrated Security=True"; SqlConnection conn = new SqlConnection(connectionString); conn.Open(); SqlCommand MyCommand = new SqlCommand(commandText, conn); MyCommand.Parameters.AddWithValue("@ds", dateTimePicker1.Value); MyCommand.Parameters.AddWithValue("@de", dateTimePicker2.Value); SqlDataAdapter dataAdapter = new SqlDataAdapter(MyCommand); DataSet ds = new DataSet(); dataAdapter.Fill(ds); dataGridView1.DataSource = ds.Tables[0];
Работа с SqlDataAdapter и DataSet
Ранее для получения данных мы использовали объект SqlDataReader, с помощью которого построчно можно перебрать ответ от сервера базы данных. Но есть и другой способ, который демонстрирует использование объектов SqlDataAdapter и DataSet. DataSet представляет хранилище данных, с которыми можно работать независимо от наличия подключения, а SqlDataAdapter заполняет DataSet данными из БД.
Для получения данных через объект SqlDataAdapter необходимо организовать подключение к БД и выполнить команду SELECT. Есть несколько способов создания SqlDataAdapter:
SqlDataAdapter adapter = new SqlDataAdapter(); SqlDataAdapter adapter = new SqlDataAdapter(command); SqlDataAdapter adapter = new SqlDataAdapter(sql, connection); SqlDataAdapter adapter = new SqlDataAdapter(sql, connectionString);
- Можно использовать конструктор без параметров, а команду SELECT и подключение установить позже
- Можно передать в конструктор объект SqlCommand
- Можно в конструкторе установить sql-выражение SELECT и объект SqlConnection
- Можно в конструкторе установить sql-выражение SELECT и строку подключения
Рассмотрим, как получить данные в DataSet через SqlDataAdapter. Для работы с DataSet особенно удобно использовать элементы управления, которые могут заполняться из внешнего источника данных, например, DataGridView в Windows Forms. Поэтому создадим новый проект по типу Windows Forms Application.
Добавим на единственную форму в проекте элемент DataGridView и определим следующий код формы:
using System.Data; using System.Windows.Forms; using System.Data.SqlClient; namespace AdoNetWinFormsApp < public partial class Form1 : Form < public Form1() < InitializeComponent(); string connectionString = @"Data Source=.\SQLEXPRESS;Initial Catalog=usersdb;Integrated Security=True"; string sql = "SELECT * FROM Users"; using (SqlConnection connection = new SqlConnection(connectionString)) < connection.Open(); // Создаем объект DataAdapter SqlDataAdapter adapter = new SqlDataAdapter(sql, connection); // Создаем объект Dataset DataSet ds = new DataSet(); // Заполняем Dataset adapter.Fill(ds); // Отображаем данные dataGridView1.DataSource = ds.Tables[0]; >> > >
В конструкторе формы в DataGridView загружаются данные. Для загрузки данных создается объект SqlDataAdapter, который принимает объект подключения и sql-выражение SELECT. Затем создается объект DataSet и с помощью метода adapter.Fill() в него загружаются данные. Дальше происходит установка источника данных для DataGridView:
dataGridView1.DataSource = ds.Tables[0];
В качестве источника устанавливается одна из таблиц в DataSet. Каждая таблица представляет объект DataTable, и в DataSet может быть определено несколько таких таблиц. Но в данном случае при выборке в DataSet есть только одна таблица, которую мы можем получить из коллекции Tables по индексу.