diff --git a/anbs_cpdb/Classes/MySqlEngine.cs b/anbs_cpdb/Classes/MySqlEngine.cs
index a5ef494..20dee85 100644
--- a/anbs_cpdb/Classes/MySqlEngine.cs
+++ b/anbs_cpdb/Classes/MySqlEngine.cs
@@ -20,14 +20,14 @@ public class MySqlEngine: IDbEngine
///
public string ConnectionString { get; set; }
- #region Небезопасные методы
+ #region Базовые операции
///
/// Выполняем команду
///
/// Запрос
- /// Данные запроса
- /// Успешно ли (есть ли хотя бы одна затронутая строки) выполнена команда
- public async Task ExecuteAsync (string sql, object model)
+ /// Данные запроса
+ /// Количество затронутых строк
+ public async Task ExecuteAsync (string sql, object values)
{
// Подключаемся к БД
await using MySqlConnection connection = new(ConnectionString);
@@ -36,17 +36,25 @@ public class MySqlEngine: IDbEngine
await connection.OpenAsync();
// Выполняем команду и выводим результат
- return await connection.ExecuteAsync(sql, model) > 0;
+ return await connection.ExecuteAsync(sql, values);
}
///
- /// Запрос на получение одной строки
+ /// Выполняем команду
+ ///
+ /// Запрос
+ /// Данные запроса
+ /// Количество затронутых строк
+ public int Execute (string sql, object values) => ExecuteAsync(sql, values).GetAwaiter().GetResult();
+
+ ///
+ /// Запрос
///
/// Тип передаваемого значения
/// Запрос
- /// Данные запроса
- /// Возвращает тип или значение по умолчанию
- public async Task QueryRowAsync (string sql, object model)
+ /// Данные запроса
+ /// Возвращает массив типа или значение по умолчанию
+ public async Task> QueryAsync (string sql, object values)
{
// Подключаемся к БД
await using MySqlConnection connection = new(ConnectionString);
@@ -55,7 +63,7 @@ public class MySqlEngine: IDbEngine
await connection.OpenAsync();
// Выполняем запрос и выводим результат
- return await connection.QueryFirstOrDefaultAsync(sql, model);
+ return await connection.QueryAsync(sql, values);
}
///
@@ -63,9 +71,18 @@ public class MySqlEngine: IDbEngine
///
/// Тип передаваемого значения
/// Запрос
- /// Данные запроса
+ /// Данные запроса
/// Возвращает массив типа или значение по умолчанию
- public async Task> QueryAsync (string sql, object model)
+ public IEnumerable Query (string sql, object values) => QueryAsync(sql, values).GetAwaiter().GetResult();
+
+ ///
+ /// Запрос строки
+ ///
+ /// Тип передаваемого значения
+ /// Запрос
+ /// Данные запроса
+ /// Возвращает массив типа или значение по умолчанию
+ public async Task QueryRowAsync (string sql, object values)
{
// Подключаемся к БД
await using MySqlConnection connection = new(ConnectionString);
@@ -74,105 +91,275 @@ public class MySqlEngine: IDbEngine
await connection.OpenAsync();
// Выполняем запрос и выводим результат
- return await connection.QueryAsync(sql, model);
+ return await connection.QuerySingleOrDefaultAsync(sql, values);
}
+ ///
+ /// Запрос строки
+ ///
+ /// Тип передаваемого значения
+ /// Запрос
+ /// Данные запроса
+ /// Возвращает массив типа или значение по умолчанию
+ public T? QueryRow (string sql, object values) => QueryRowAsync(sql, values).GetAwaiter().GetResult();
+
#endregion
- #region Получение
+
+ #region Получение данных
+ ///
+ /// Получает массив данных (SELECT * FROM...)
+ ///
+ /// Тип получаемых данных
+ /// SQL-запрос
+ /// Данные запроса
+ /// Массив результата запроса
+ public async Task> GetResultsAsync (string sql, object values) => await QueryAsync(sql, values);
///
- /// Выборка данных из таблицы
+ /// Получает массив данных (SELECT * FROM...)
///
- /// Тип данных
- /// Имя таблицы
- /// Выбор столбцов таблицы, которые должны попасть в выборку (пустая -- все)
- /// Массив значений столбцов, которые должны попасть в выборку
- /// Сортировка
- /// Сколько максимально элементов должно быть в выборке (0 -- без ограничения)
- /// Массив типа
- public async Task> SelectAsync(string table, string[] columns,
- List> where, string? orderBy, int limit = 0)
+ /// Тип получаемых данных
+ /// SQL-запрос
+ /// Данные запроса
+ /// Массив результата запроса
+ public IEnumerable GetResults (string sql, object values) => GetResultsAsync(sql, values).GetAwaiter().GetResult();
+
+ ///
+ /// Получает строку в массиве данных
+ ///
+ /// Тип получаемых данных
+ /// SQL-запрос
+ /// Данные запроса
+ /// Строки данных или null
+ public async Task GetRowAsync (string sql, object values)
{
- // Формирую запрос
+ // Подключаемся к БД
+ await using MySqlConnection connection = new(ConnectionString);
+
+ // Открываем соединение
+ await connection.OpenAsync();
+
+ // Выполняем запрос и выводим результат
+ return await connection.QuerySingleOrDefaultAsync(sql, values);
+ }
+
+ ///
+ /// Получает строку в массиве данных
+ ///
+ /// Тип получаемых данных
+ /// SQL-запрос
+ /// Данные запроса
+ /// Строки данных или null
+ public T? GetRow (string sql, object values) => GetRowAsync(sql, values).GetAwaiter().GetResult();
+
+ ///
+ /// Получает колонку в массиве данных
+ ///
+ /// Тип получаемых данных
+ /// SQL-запрос
+ /// Данные запроса
+ /// Колонка данных или null
+ public async Task> GetColAsync (string sql, object values)
+ where T : IComparable, IConvertible, IEquatable => await QueryAsync(sql, values);
+
+ ///
+ /// Получает колонку в массиве данных
+ ///
+ /// Тип получаемых данных
+ /// SQL-запрос
+ /// Данные запроса
+ /// Колонка данных или null
+ public IEnumerable GetCol (string sql, object values) where T : IComparable, IConvertible, IEquatable =>
+ GetColAsync(sql, values).GetAwaiter().GetResult();
+
+ ///
+ /// Получение значение единичного поля
+ ///
+ /// Тип получаемых данных
+ /// SQL-запрос
+ /// Данные запроса
+ /// Поле или null
+ public async Task GetVarAsync (string sql, object values) where T : IComparable, IConvertible, IEquatable
+ {
+ // Подключаемся к БД
+ await using MySqlConnection connection = new(ConnectionString);
+
+ // Открываем соединение
+ await connection.OpenAsync();
+
+ // Выполняем запрос и выводим результат
+ return await connection.QuerySingleOrDefaultAsync(sql, values);
+ }
+
+ ///
+ /// Получение значение единичного поля
+ ///
+ /// Тип получаемых данных
+ /// SQL-запрос
+ /// Данные запроса
+ /// Поле или null
+ public T? GetVar (string sql, object values) where T : IComparable, IConvertible, IEquatable =>
+ GetVarAsync(sql, values).GetAwaiter().GetResult();
+
+ #endregion
+
+ #region CRUD данные
+
+ ///
+ /// Вставляет данные в таблицу
+ ///
+ /// Класс данных
+ /// Данные
+ /// Имя таблицы
+ /// Результат выполнения
+ public async Task InsertAsync (T data, string tableName) where T : class
+ {
+ // Получение список имён свойств в data
+ List propertyNamesList = (from dataProperty in data.GetType().GetProperties() select dataProperty.Name).ToList();
+
+ // Получаем список имён в data, обрамленные @
+ List propertyValuesList = propertyNamesList.Select(static propertyName => $"@{propertyName}").ToList();
+
+ //Получаем строку имён свойств
+ string propertyNames = string.Join(", ", propertyNamesList.ToArray());
+
+ // Получаем строку имён свойств, обрамленных @
+ string propertyValues = string.Join(", ", propertyValuesList.ToArray());
+
+ // Создаю соединение
+ await using MySqlConnection connection = new(ConnectionString);
+
+ // Создаю запрос
string sql = $"""
- SELECT
- {(columns.Any() ? string.Join(", ", columns) : "*")}
- FROM {table}
- """;
-
- // Создаю массив where параметров
- List whereCondition = new();
-
- // Создаю массив значений
- List paramsValues = new();
-
- // Если заданы параметры where
- if (where.Any())
- {
- // - то формирую массив where из where-запроса
- whereCondition.AddRange(where.Select(static whereItem => $"{whereItem.Key}=@{whereItem.Key}"));
- // - и значения параметров
- paramsValues.AddRange(where.Select(static whereItem => $"@{whereItem.Key}={whereItem.Value}"));
- }
-
- // Если массив where параметров не пуст
- if (whereCondition.Any())
- // - то добавляю к запросу
- sql += $" WHERE {string.Join(", ", whereCondition.ToArray())}";
-
- // Если добавлена сортировка
- if (orderBy != null)
- // - то добавляю сортировку к запросу
- sql += $" ORDER BY {orderBy}";
-
- // Если установлено запрашиваемое число элементов
- if (limit > 0)
- // - то вводим ограничение
- sql += $" LIMIT {limit}";
-
- // Осуществляю запрос и возвращаю результат
- return await QueryAsync(sql, paramsValues.ToArray());
- }
-
- ///
- /// Выборка строки из таблицы
- ///
- /// Тип данных
- /// Имя таблицы
- /// Выбор столбцов таблицы, которые должны попасть в выборку (пустая -- все)
- /// Массив значений столбцов, которые должны попасть в выборку
- /// Сортировка
- /// Тип или null
- public async Task SelectRowAsync(string table, string[] columns, List> where,
- string? orderBy = null) => (await SelectAsync(table, columns, where, orderBy, 1)).FirstOrDefault();
-
- #endregion
-
- #region Вычисление числа элементов в таблице
-///
-/// Вычисляет число строк в таблице
-///
-/// Таблица
-/// Число строк в таблице
- public async Task CountAsync(string table)
- {
- // Задаю запрос
- string sql = $"SELECT COUNT(*) FROM {table}";
+ INSERT
+ INTO {tableName} ({propertyNames})
+ VALUES ({propertyValues})
+ """;
// Выполняю запрос
- return (await QueryAsync(sql, new())).FirstOrDefault();
+ return await connection.ExecuteAsync(sql, data) > 0;
}
+ ///
+ /// Вставляет данные в таблицу
+ ///
+ /// Класс данных
+ /// Данные
+ /// Имя таблицы
+ /// Результат выполнения
+ public bool Insert (T data, string tableName) where T : class => InsertAsync(data, tableName).GetAwaiter().GetResult();
+
+ ///
+ /// Обновляет строку в таблице
+ ///
+ /// Класс данных
+ /// Данные
+ /// Имя таблицы
+ /// Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data
+ /// Результат выполнения
+ public async Task UpdateAsync (T data, string tableName, string whereConditionColumn) where T : class
+ {
+ // Получение список имён свойств в data
+ List propertyNamesList = (from dataProperty in data.GetType().GetProperties()
+ where dataProperty.Name != whereConditionColumn
+ select dataProperty.Name).ToList();
+
+ // Получаем список имён в data, обрамленные @
+ List propertyKeyValuesList = propertyNamesList.Select(static propertyName => $"{propertyName}=@{propertyName}").ToList();
+
+ // Получаем строку имён свойств, обрамленных @
+ string properties = string.Join(", ", propertyKeyValuesList.ToArray());
+
+ // Создаю соединение
+ await using MySqlConnection connection = new(ConnectionString);
+
+ // Создаю запрос
+ string sql = $"""
+ UPDATE
+ {tableName}
+ SET
+ ({properties})
+ WHERE
+ {whereConditionColumn}=@{whereConditionColumn}
+ """;
+
+ // Выполняю запрос
+ return await connection.ExecuteAsync(sql, data) > 0;
+ }
+
+ ///
+ /// Обновляет строку в таблице
+ ///
+ /// Класс данных
+ /// Данные
+ /// Имя таблицы
+ /// Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data
+ /// Результат выполнения
+ public bool Update (T data, string tableName, string whereConditionColumn) where T : class =>
+ UpdateAsync(data, tableName, whereConditionColumn).GetAwaiter().GetResult();
+
+ ///
+ /// Удаляет строки
+ ///
+ /// Имя таблицы
+ /// Условие
+ /// Результат выполнения
+ public async Task DeleteAsync (string tableName, KeyValue where)
+ {
+ // Создаю соединение
+ await using MySqlConnection connection = new(ConnectionString);
+
+ // Создаю запрос
+ string sql = $"""
+ DELETE FROM
+ {tableName}
+ WHERE
+ {where.Key}=@{where.Key}
+ """;
+
+ // Выполняю запрос
+ return await connection.ExecuteAsync(sql, new { where.Value }) > 0;
+ }
+
+ ///
+ /// Удаляет строки
+ ///
+ /// Имя таблицы
+ /// Условие
+ /// Результат выполнения
+ public bool Delete (string tableName, KeyValue where) => DeleteAsync(tableName, where).GetAwaiter().GetResult();
+
+ ///
+ /// Удаляет строку
+ ///
+ /// Имя таблицы
+ /// Условие
+ /// Результат выполнения
+ public async Task DeleteRowAsync (string tableName, KeyValue where)
+ {
+ // Создаю соединение
+ await using MySqlConnection connection = new(ConnectionString);
+
+ // Создаю запрос
+ string sql = $"""
+ DELETE FROM
+ {tableName}
+ WHERE
+ {where.Key}=@{where.Key}
+ LIMIT 1
+ """;
+
+ // Выполняю запрос
+ return await connection.ExecuteAsync(sql, new { where.Value }) > 0;
+ }
+
+ ///
+ /// Удаляет строку
+ ///
+ /// Имя таблицы
+ /// Условие
+ /// Результат выполнения
+ public bool DeleteRow (string tableName, KeyValue where) => DeleteRowAsync(tableName, where).GetAwaiter().GetResult();
#endregion
-
- public async Task InsertAsync (string table, T entity, KeyValue primaryIndex) => throw new NotImplementedException();
-
- public async Task InsertUpdateAsync (string table, T entity) => throw new NotImplementedException();
-
- public async Task UpdateAsync (string table, T entity, KeyValue where) => throw new NotImplementedException();
-
- public async Task DeleteAsync (string table, KeyValue where) => throw new NotImplementedException();
-
- public async Task DeleteRowAsync (string table, KeyValue where) => throw new NotImplementedException();
}
\ No newline at end of file
diff --git a/anbs_cpdb/Interfaces/IDbEngine.cs b/anbs_cpdb/Interfaces/IDbEngine.cs
index 0150450..672eed1 100644
--- a/anbs_cpdb/Interfaces/IDbEngine.cs
+++ b/anbs_cpdb/Interfaces/IDbEngine.cs
@@ -12,84 +12,206 @@ public interface IDbEngine
///
string ConnectionString { get; set; }
- #region Небезопасные методы
-
- Task ExecuteAsync (string sql, object model);
+ #region Базовые операции
///
- /// Запрос на получение одной строки
+ /// Выполняем команду
///
- /// Тип передаваемого значения
/// Запрос
- /// Данные запроса
- /// Возвращает тип или значение по умолчанию
- Task QueryRowAsync (string sql, object model);
+ /// Данные запроса
+ /// Количество затронутых строк
+ Task ExecuteAsync (string sql, object values);
+
+ ///
+ /// Выполняем команду
+ ///
+ /// Запрос
+ /// Данные запроса
+ /// Количество затронутых строк
+ int Execute (string sql, object values);
///
/// Запрос
///
/// Тип передаваемого значения
/// Запрос
- /// Данные запроса
+ /// Данные запроса
/// Возвращает массив типа или значение по умолчанию
- Task> QueryAsync (string sql, object model);
-
- #endregion
-
- #region Получение
+ Task> QueryAsync (string sql, object values);
///
- /// Выборка данных из таблицы
+ /// Запрос
///
- /// Тип данных
- /// Имя таблицы
- /// Выбор столбцов таблицы, которые должны попасть в выборку (пустая -- все)
- /// Массив значений столбцов, которые должны попасть в выборку
- /// Сортировка
- /// Сколько максимально элементов должно быть в выборке (0 -- без ограничения)
- /// Массив типа
- Task> SelectAsync (string table, string[] columns, List> where, string? orderBy, int limit = 0);
+ /// Тип передаваемого значения
+ /// Запрос
+ /// Данные запроса
+ /// Возвращает массив типа или значение по умолчанию
+ IEnumerable Query (string sql, object values);
///
- /// Выборка строки из таблицы
+ /// Запрос строки
///
- /// Тип данных
- /// Имя таблицы
- /// Выбор столбцов таблицы, которые должны попасть в выборку (пустая -- все)
- /// Массив значений столбцов, которые должны попасть в выборку
- /// Сортировка
- /// Тип или null
- Task SelectRowAsync (string table, string[] columns, List> where, string? orderBy = null);
- #endregion
+ /// Тип передаваемого значения
+ /// Запрос
+ /// Данные запроса
+ /// Возвращает массив типа или значение по умолчанию
+ Task QueryRowAsync (string sql, object values);
- #region Вычисление числа элементов в таблице
///
- /// Вычисляет число строк в таблице
+ /// Запрос строки
///
- /// Таблица
- /// Число строк в таблице
- Task CountAsync (string table);
+ /// Тип передаваемого значения
+ /// Запрос
+ /// Данные запроса
+ /// Возвращает массив типа или значение по умолчанию
+ T? QueryRow (string sql, object values);
#endregion
- #region Добавление строки в таблицу
+ #region Получение данных
- Task InsertAsync (string table, T entity, KeyValue primaryIndex);
+ ///
+ /// Получает массив данных (SELECT * FROM...)
+ ///
+ /// Тип получаемых данных
+ /// SQL-запрос
+ /// Данные запроса
+ /// Массив результата запроса
+ Task> GetResultsAsync (string sql, object values);
- Task InsertUpdateAsync (string table, T entity);
+ ///
+ /// Получает массив данных (SELECT * FROM...)
+ ///
+ /// Тип получаемых данных
+ /// SQL-запрос
+ /// Данные запроса
+ /// Массив результата запроса
+ IEnumerable GetResults (string sql, object values);
+
+ ///
+ /// Получает строку в массиве данных
+ ///
+ /// Тип получаемых данных
+ /// SQL-запрос
+ /// Данные запроса
+ /// Строки данных или null
+ Task GetRowAsync (string sql, object values);
+
+ ///
+ /// Получает строку в массиве данных
+ ///
+ /// Тип получаемых данных
+ /// SQL-запрос
+ /// Данные запроса
+ /// Строки данных или null
+ T? GetRow (string sql, object values);
+
+ ///
+ /// Получает колонку в массиве данных
+ ///
+ /// Тип получаемых данных
+ /// SQL-запрос
+ /// Данные запроса
+ /// Колонка данных или null
+ Task> GetColAsync (string sql, object values) where T : IComparable, IConvertible, IEquatable;
+
+ ///
+ /// Получает колонку в массиве данных
+ ///
+ /// Тип получаемых данных
+ /// SQL-запрос
+ /// Данные запроса
+ /// Колонка данных или null
+ IEnumerable GetCol (string sql, object values) where T : IComparable, IConvertible, IEquatable;
+
+ ///
+ /// Получение значение единичного поля
+ ///
+ /// Тип получаемых данных
+ /// SQL-запрос
+ /// Данные запроса
+ /// Поле или null
+ Task GetVarAsync (string sql, object values) where T : IComparable, IConvertible, IEquatable;
+
+ ///
+ /// Получение значение единичного поля
+ ///
+ /// Тип получаемых данных
+ /// SQL-запрос
+ /// Данные запроса
+ /// Поле или null
+ T? GetVar (string sql, object values) where T : IComparable, IConvertible, IEquatable;
#endregion
- #region Обновление строки в таблице
+ #region CRUD данные
+ ///
+ /// Вставляет данные в таблицу
+ ///
+ /// Класс данных
+ /// Данные
+ /// Имя таблицы
+ /// Результат выполнения
+ Task InsertAsync (T data, string tableName) where T : class;
- Task UpdateAsync (string table, T entity, KeyValue where);
+ ///
+ /// Вставляет данные в таблицу
+ ///
+ /// Класс данных
+ /// Данные
+ /// Имя таблицы
+ /// Результат выполнения
+ bool Insert (T data, string tableName) where T : class;
- #endregion
+ ///
+ /// Обновляет строку в таблице
+ ///
+ /// Класс данных
+ /// Данные
+ /// Имя таблицы
+ /// Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data
+ /// Результат выполнения
+ Task UpdateAsync (T data, string tableName, string whereConditionColumn) where T : class;
- #region Удаление строк
+ ///
+ /// Обновляет строку в таблице
+ ///
+ /// Класс данных
+ /// Данные
+ /// Имя таблицы
+ /// Условие поиска строки. ВНИМАНИЕ! Должно быть одним из указанных свойств типа класса data
+ /// Результат выполнения
+ bool Update (T data, string tableName, string whereConditionColumn) where T : class;
- Task DeleteAsync (string table, KeyValue where);
+ ///
+ /// Удаляет строки
+ ///
+ /// Имя таблицы
+ /// Условие
+ /// Результат выполнения
+ Task DeleteAsync (string tableName, KeyValue where);
- Task DeleteRowAsync (string table, KeyValue where);
+ ///
+ /// Удаляет строки
+ ///
+ /// Имя таблицы
+ /// Условие
+ /// Результат выполнения
+ bool Delete (string tableName, KeyValue where);
+ ///
+ /// Удаляет строку
+ ///
+ /// Имя таблицы
+ /// Условие
+ /// Результат выполнения
+ Task DeleteRowAsync (string tableName, KeyValue where);
+
+ ///
+ /// Удаляет строку
+ ///
+ /// Имя таблицы
+ /// Условие
+ /// Результат выполнения
+ bool DeleteRow (string tableName, KeyValue where);
#endregion
}
\ No newline at end of file
diff --git a/anbs_cpdb/anbs_cpdb.csproj b/anbs_cpdb/anbs_cpdb.csproj
index fd807b8..a96949b 100644
--- a/anbs_cpdb/anbs_cpdb.csproj
+++ b/anbs_cpdb/anbs_cpdb.csproj
@@ -8,7 +8,7 @@
anbs_cp.Database
True
ANBSoftware.ComponentsPack.Database
- 2023.08.18
+ 2023.08.19
Александр Бабаев
Набор компонентов ANB Software для работы с БД
Библиотека полезных методов языка C# для работы с базами данных
@@ -22,6 +22,7 @@
+