Zamiast używać bibliotek zewnętrznych do operacji zapytań, wolałbym raczej pisać zapytania we własnym zakresie. Ponieważ korzystanie z jakichkolwiek pakietów innych firm odbierałoby główną zaletę korzystania z programu dapper, tj. Elastyczność pisania zapytań.
Teraz występuje problem z pisaniem zapytania wstawiania lub aktualizacji dla całego obiektu. W tym celu można po prostu utworzyć pomocników, takich jak poniżej:
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;
}
Teraz, po prostu przekazując nazwę kolumn do wstawienia, całe zapytanie zostanie utworzone automatycznie, jak poniżej:
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);
Można również zmodyfikować funkcję, aby zwracała całą instrukcję INSERT, przekazując parametr TableName.
Upewnij się, że nazwy właściwości Class są zgodne z nazwami pól w bazie danych. Wtedy tylko Ty możesz przekazać cały obiekt (jak w naszym przypadku userObj), a wartości zostaną automatycznie zmapowane.
W ten sam sposób możesz również mieć funkcję pomocniczą dla zapytania 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(',', ' ');
}
I używaj go w następujący sposób:
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);
Chociaż w tych funkcjach pomocniczych również musisz przekazać nazwę pól, które chcesz wstawić lub zaktualizować, ale przynajmniej masz pełną kontrolę nad zapytaniem i możesz również zawierać różne klauzule WHERE, gdy jest to wymagane.
Dzięki tym funkcjom pomocniczym zapisujesz następujące wiersze kodu:
Wstaw zapytanie:
$ "INSERT INTO UserDetails (UserName,City) VALUES (@UserName,@City) RETURNING UserId";
W przypadku zapytania o aktualizację:
$"UPDATE UserDetails SET UserName=@UserName, City=@City WHERE UserId=@UserId";
Wydaje się, że istnieje różnica kilku linii kodu, ale jeśli chodzi o wykonywanie operacji wstawiania lub aktualizacji z tabelą zawierającą więcej niż 10 pól, można poczuć różnicę.
Możesz użyć operatora nameof, aby przekazać nazwę pola w funkcji, aby uniknąć literówek
Zamiast:
List < string > columns = new List < string > {
"UserName",
"City"
}
Możesz pisać:
List < string > columns = new List < string > {
nameof(UserEntity.UserName),
nameof(UserEntity.City),
}