Замість використання будь-якої сторонньої бібліотеки для операцій із запитами, я б краще запропонувати писати запити самостійно. Оскільки використання будь-яких інших пакетів третьої сторони забирає головну перевагу використання Dapper, тобто гнучкості для запиту запитів.
Тепер виникла проблема із написанням Insert або Update query для всього об’єкта. Для цього можна просто створити помічників, як показано нижче:
InsertQueryBuilder:
public static string InsertQueryBuilder(IEnumerable < string > fields) {
StringBuilder columns = new StringBuilder();
StringBuilder values = new StringBuilder();
foreach(string columnName in fields) {
columns.Append($ "{columnName}, ");
values.Append($ "@{columnName}, ");
}
string insertQuery = $ "({ columns.ToString().TrimEnd(',', ' ')}) VALUES ({ values.ToString().TrimEnd(',', ' ')}) ";
return insertQuery;
}
Тепер, просто передавши назву стовпців, які потрібно вставити, весь запит буде створений автоматично, як нижче:
List < string > columns = new List < string > {
"UserName",
"City"
}
//QueryBuilder is the class having the InsertQueryBuilder()
string insertQueryValues = QueryBuilderUtil.InsertQueryBuilder(columns);
string insertQuery = $ "INSERT INTO UserDetails {insertQueryValues} RETURNING UserId";
Guid insertedId = await _connection.ExecuteScalarAsync < Guid > (insertQuery, userObj);
Ви також можете змінити функцію повернення всього оператора INSERT, передавши параметр TableName.
Переконайтесь, що назви властивостей Class збігаються з іменами полів у базі даних. Тоді тільки ви можете передавати весь obj (як у нашому випадку userObj), і значення будуть автоматично відображатися.
Таким же чином, ви можете мати функцію помічника для UPDATE запиту:
public static string UpdateQueryBuilder(List < string > fields) {
StringBuilder updateQueryBuilder = new StringBuilder();
foreach(string columnName in fields) {
updateQueryBuilder.AppendFormat("{0}=@{0}, ", columnName);
}
return updateQueryBuilder.ToString().TrimEnd(',', ' ');
}
І використовувати його так:
List < string > columns = new List < string > {
"UserName",
"City"
}
//QueryBuilder is the class having the UpdateQueryBuilder()
string updateQueryValues = QueryBuilderUtil.UpdateQueryBuilder(columns);
string updateQuery = $"UPDATE UserDetails SET {updateQueryValues} WHERE UserId=@UserId";
await _connection.ExecuteAsync(updateQuery, userObj);
Хоча в цих допоміжних функціях також потрібно передати ім’я полів, які ви хочете вставити чи оновити, але принаймні ви маєте повний контроль над запитом, а також можете включати різні пункти WHERE як і коли потрібно.
За допомогою цих допоміжних функцій ви збережете наступні рядки коду:
Для вставки запиту:
$ "INSERT INTO UserDetails (UserName,City) VALUES (@UserName,@City) RETURNING UserId";
Для оновлення запиту:
$"UPDATE UserDetails SET UserName=@UserName, City=@City WHERE UserId=@UserId";
Здається, є різниця в декількох рядках коду, але коли мова йде про виконання операцій вставки або оновлення з таблицею, що містить більше 10 полів, можна відчути різницю.
Ви можете використовувати оператор nameof, щоб передати ім'я поля у функції, щоб уникнути помилок
Замість:
List < string > columns = new List < string > {
"UserName",
"City"
}
Ви можете написати:
List < string > columns = new List < string > {
nameof(UserEntity.UserName),
nameof(UserEntity.City),
}