Refactor user entities and repositories, update seeders

Standardized property naming in user-related entities to use 'Id' suffix (e.g., UserAccountId). Moved and updated repository interfaces and implementations to the DataAccessLayer.Repositories namespace. Refactored DBSeed seeders to use repository classes and improved structure. Updated .gitignore and project references
This commit is contained in:
Aaron Po
2026-01-15 13:23:41 -05:00
parent 60ef65ec52
commit b8cd855916
16 changed files with 660 additions and 760 deletions

1
.gitignore vendored
View File

@@ -431,3 +431,4 @@ FodyWeavers.xsd
*/data_source/other */data_source/other
.fake .fake
.idea

View File

@@ -1,5 +1,6 @@
using DataAccessLayer; using DataAccessLayer;
using DataAccessLayer.Entities; using DataAccessLayer.Entities;
using DataAccessLayer.Repositories;
namespace BusinessLayer.Services namespace BusinessLayer.Services
{ {

View File

@@ -1,20 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using DataAccessLayer; using DataAccessLayer;
using DataAccessLayer.Entities; using DataAccessLayer.Entities;
using Xunit; using DataAccessLayer.Repositories;
namespace DALTests namespace DALTests
{ {
public class UserAccountRepositoryTests public class UserAccountRepositoryTests
{ {
private readonly IUserAccountRepository _repository; private readonly IUserAccountRepository _repository = new UserAccountRepository();
public UserAccountRepositoryTests()
{
_repository = new UserAccountRepository();
}
[Fact] [Fact]
public void Add_ShouldInsertUserAccount() public void Add_ShouldInsertUserAccount()
@@ -22,7 +14,7 @@ namespace DALTests
// Arrange // Arrange
var userAccount = new UserAccount var userAccount = new UserAccount
{ {
UserAccountID = Guid.NewGuid(), UserAccountId = Guid.NewGuid(),
Username = "testuser", Username = "testuser",
FirstName = "Test", FirstName = "Test",
LastName = "User", LastName = "User",
@@ -33,7 +25,7 @@ namespace DALTests
// Act // Act
_repository.Add(userAccount); _repository.Add(userAccount);
var retrievedUser = _repository.GetById(userAccount.UserAccountID); var retrievedUser = _repository.GetById(userAccount.UserAccountId);
// Assert // Assert
Assert.NotNull(retrievedUser); Assert.NotNull(retrievedUser);
@@ -47,7 +39,7 @@ namespace DALTests
var userId = Guid.NewGuid(); var userId = Guid.NewGuid();
var userAccount = new UserAccount var userAccount = new UserAccount
{ {
UserAccountID = userId, UserAccountId = userId,
Username = "existinguser", Username = "existinguser",
FirstName = "Existing", FirstName = "Existing",
LastName = "User", LastName = "User",
@@ -62,7 +54,7 @@ namespace DALTests
// Assert // Assert
Assert.NotNull(retrievedUser); Assert.NotNull(retrievedUser);
Assert.Equal(userId, retrievedUser.UserAccountID); Assert.Equal(userId, retrievedUser.UserAccountId);
} }
[Fact] [Fact]
@@ -71,7 +63,7 @@ namespace DALTests
// Arrange // Arrange
var userAccount = new UserAccount var userAccount = new UserAccount
{ {
UserAccountID = Guid.NewGuid(), UserAccountId = Guid.NewGuid(),
Username = "updatableuser", Username = "updatableuser",
FirstName = "Updatable", FirstName = "Updatable",
LastName = "User", LastName = "User",
@@ -84,7 +76,7 @@ namespace DALTests
// Act // Act
userAccount.FirstName = "Updated"; userAccount.FirstName = "Updated";
_repository.Update(userAccount); _repository.Update(userAccount);
var updatedUser = _repository.GetById(userAccount.UserAccountID); var updatedUser = _repository.GetById(userAccount.UserAccountId);
// Assert // Assert
Assert.NotNull(updatedUser); Assert.NotNull(updatedUser);
@@ -97,7 +89,7 @@ namespace DALTests
// Arrange // Arrange
var userAccount = new UserAccount var userAccount = new UserAccount
{ {
UserAccountID = Guid.NewGuid(), UserAccountId = Guid.NewGuid(),
Username = "deletableuser", Username = "deletableuser",
FirstName = "Deletable", FirstName = "Deletable",
LastName = "User", LastName = "User",
@@ -108,8 +100,8 @@ namespace DALTests
_repository.Add(userAccount); _repository.Add(userAccount);
// Act // Act
_repository.Delete(userAccount.UserAccountID); _repository.Delete(userAccount.UserAccountId);
var deletedUser = _repository.GetById(userAccount.UserAccountID); var deletedUser = _repository.GetById(userAccount.UserAccountId);
// Assert // Assert
Assert.Null(deletedUser); Assert.Null(deletedUser);
@@ -121,7 +113,7 @@ namespace DALTests
// Arrange // Arrange
var user1 = new UserAccount var user1 = new UserAccount
{ {
UserAccountID = Guid.NewGuid(), UserAccountId = Guid.NewGuid(),
Username = "user1", Username = "user1",
FirstName = "User", FirstName = "User",
LastName = "One", LastName = "One",
@@ -131,7 +123,7 @@ namespace DALTests
}; };
var user2 = new UserAccount var user2 = new UserAccount
{ {
UserAccountID = Guid.NewGuid(), UserAccountId = Guid.NewGuid(),
Username = "user2", Username = "user2",
FirstName = "User", FirstName = "User",
LastName = "Two", LastName = "Two",
@@ -158,7 +150,7 @@ namespace DALTests
{ {
new UserAccount new UserAccount
{ {
UserAccountID = Guid.NewGuid(), UserAccountId = Guid.NewGuid(),
Username = $"pageuser_{Guid.NewGuid():N}", Username = $"pageuser_{Guid.NewGuid():N}",
FirstName = "Page", FirstName = "Page",
LastName = "User", LastName = "User",
@@ -168,7 +160,7 @@ namespace DALTests
}, },
new UserAccount new UserAccount
{ {
UserAccountID = Guid.NewGuid(), UserAccountId = Guid.NewGuid(),
Username = $"pageuser_{Guid.NewGuid():N}", Username = $"pageuser_{Guid.NewGuid():N}",
FirstName = "Page", FirstName = "Page",
LastName = "User", LastName = "User",
@@ -178,7 +170,7 @@ namespace DALTests
}, },
new UserAccount new UserAccount
{ {
UserAccountID = Guid.NewGuid(), UserAccountId = Guid.NewGuid(),
Username = $"pageuser_{Guid.NewGuid():N}", Username = $"pageuser_{Guid.NewGuid():N}",
FirstName = "Page", FirstName = "Page",
LastName = "User", LastName = "User",

View File

@@ -12,6 +12,10 @@
Include="Konscious.Security.Cryptography.Argon2" Include="Konscious.Security.Cryptography.Argon2"
Version="1.3.1" Version="1.3.1"
/> />
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.1.2" /> <PackageReference Include="Microsoft.Data.SqlClient" Version="6.1.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DataAccessLayer\DataAccessLayer.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -1,6 +1,9 @@
using Microsoft.Data.SqlClient; using Microsoft.Data.SqlClient;
interface ISeeder namespace DBSeed
{ {
internal interface ISeeder
{
Task SeedAsync(SqlConnection connection); Task SeedAsync(SqlConnection connection);
}
} }

View File

@@ -1,10 +1,11 @@
using System.Data; using System.Data;
using Microsoft.Data.SqlClient; using Microsoft.Data.SqlClient;
namespace DBSeed; namespace DBSeed
class LocationSeeder : ISeeder
{ {
internal class LocationSeeder : ISeeder
{
private static readonly IReadOnlyList<( private static readonly IReadOnlyList<(
string CountryName, string CountryName,
string CountryCode string CountryCode
@@ -15,11 +16,10 @@ class LocationSeeder : ISeeder
("United States", "US"), ("United States", "US"),
]; ];
private static readonly IReadOnlyList<( private static IReadOnlyList<(string StateProvinceName, string StateProvinceCode, string CountryCode)> States
string StateProvinceName, {
string StateProvinceCode, get;
string CountryCode } =
)> States =
[ [
("Alabama", "US-AL", "US"), ("Alabama", "US-AL", "US"),
("Alaska", "US-AK", "US"), ("Alaska", "US-AK", "US"),
@@ -124,10 +124,7 @@ class LocationSeeder : ISeeder
("Ciudad de México", "MX-CMX", "MX"), ("Ciudad de México", "MX-CMX", "MX"),
]; ];
private static readonly IReadOnlyList<( private static IReadOnlyList<(string StateProvinceCode, string CityName)> Cities { get; } =
string StateProvinceCode,
string CityName
)> Cities =
[ [
("US-CA", "Los Angeles"), ("US-CA", "Los Angeles"),
("US-CA", "San Diego"), ("US-CA", "San Diego"),
@@ -327,4 +324,5 @@ class LocationSeeder : ISeeder
await command.ExecuteNonQueryAsync(); await command.ExecuteNonQueryAsync();
} }
}
} }

View File

@@ -1,14 +1,20 @@
using System.Data; using System.Data;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
using DataAccessLayer.Entities;
using DataAccessLayer.Repositories;
using idunno.Password; using idunno.Password;
using Konscious.Security.Cryptography; using Konscious.Security.Cryptography;
using Microsoft.Data.SqlClient; using Microsoft.Data.SqlClient;
namespace DBSeed; namespace DBSeed
class UserSeeder : ISeeder
{ {
internal class UserSeeder : ISeeder
{
private UserAccountRepository _userAccountRepository = new UserAccountRepository();
private static readonly IReadOnlyList<( private static readonly IReadOnlyList<(
string FirstName, string FirstName,
string LastName string LastName
@@ -119,40 +125,25 @@ class UserSeeder : ISeeder
public async Task SeedAsync(SqlConnection connection) public async Task SeedAsync(SqlConnection connection)
{ {
var generator = new PasswordGenerator(); var generator = new PasswordGenerator();
var random = new Random(); var rng = new Random();
int createdUsers = 0; int createdUsers = 0;
int createdCredentials = 0; int createdCredentials = 0;
int createdVerifications = 0; int createdVerifications = 0;
foreach (var (firstName, lastName) in SeedNames) foreach (var (firstName, lastName) in SeedNames)
{ {
string username = BuildUsername(firstName, lastName); // create the user in the database
string email = BuildEmail(firstName, lastName); var ua = new UserAccount
Guid? existingId =
await GetUserAccountIdByUsernameAsync(connection, username)
?? await GetUserAccountIdByEmailAsync(connection, email);
Guid userAccountId;
if (existingId.HasValue)
{ {
userAccountId = existingId.Value; FirstName = firstName,
} LastName = lastName,
else Email = $"{firstName}.{lastName}@thebiergarten.app",
{ Username = $"{firstName[0]}.{lastName}",
userAccountId = Guid.NewGuid(); DateOfBirth = GenerateDateOfBirth(rng)
DateTime dateOfBirth = GenerateDateOfBirth(random); };
await CreateUserAccountAsync(
connection,
userAccountId,
username,
firstName,
lastName,
email,
dateOfBirth
);
createdUsers++;
}
// add user credentials
if (!await HasUserCredentialAsync(connection, userAccountId)) if (!await HasUserCredentialAsync(connection, userAccountId))
{ {
string pwd = generator.Generate( string pwd = generator.Generate(
@@ -165,12 +156,11 @@ class UserSeeder : ISeeder
createdCredentials++; createdCredentials++;
} }
if (!await HasUserVerificationAsync(connection, userAccountId)) // add user verification
{ if (await HasUserVerificationAsync(connection, userAccountId)) continue;
await AddUserVerificationAsync(connection, userAccountId); await AddUserVerificationAsync(connection, userAccountId);
createdVerifications++; createdVerifications++;
} }
}
Console.WriteLine($"Created {createdUsers} user accounts."); Console.WriteLine($"Created {createdUsers} user accounts.");
Console.WriteLine($"Added {createdCredentials} user credentials."); Console.WriteLine($"Added {createdCredentials} user credentials.");
@@ -193,73 +183,16 @@ class UserSeeder : ISeeder
return $"{Convert.ToBase64String(salt)}:{Convert.ToBase64String(hash)}"; return $"{Convert.ToBase64String(salt)}:{Convert.ToBase64String(hash)}";
} }
private static async Task<Guid?> GetUserAccountIdByUsernameAsync(
SqlConnection connection,
string username
)
{
await using var command = new SqlCommand(
"usp_GetUserAccountByUsername",
connection
);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("@Username", username);
await using var reader = await command.ExecuteReaderAsync();
return await reader.ReadAsync() ? reader.GetGuid(0) : null;
}
private static async Task<Guid?> GetUserAccountIdByEmailAsync(
SqlConnection connection,
string email
)
{
await using var command = new SqlCommand(
"usp_GetUserAccountByEmail",
connection
);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("@Email", email);
await using var reader = await command.ExecuteReaderAsync();
return await reader.ReadAsync() ? reader.GetGuid(0) : null;
}
private static async Task CreateUserAccountAsync(
SqlConnection connection,
Guid userAccountId,
string username,
string firstName,
string lastName,
string email,
DateTime dateOfBirth
)
{
await using var command = new SqlCommand(
"usp_CreateUserAccount",
connection
);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("@UserAccountId", userAccountId);
command.Parameters.AddWithValue("@Username", username);
command.Parameters.AddWithValue("@FirstName", firstName);
command.Parameters.AddWithValue("@LastName", lastName);
command.Parameters.AddWithValue("@DateOfBirth", dateOfBirth);
command.Parameters.AddWithValue("@Email", email);
await command.ExecuteNonQueryAsync();
}
private static async Task<bool> HasUserCredentialAsync( private static async Task<bool> HasUserCredentialAsync(
SqlConnection connection, SqlConnection connection,
Guid userAccountId Guid userAccountId
) )
{ {
const string sql = """ const string sql = $"""
SELECT 1 SELECT 1
FROM dbo.UserCredential FROM dbo.UserCredential
WHERE UserAccountId = @UserAccountId; WHERE UserAccountId = @UserAccountId;
"""; """;
await using var command = new SqlCommand(sql, connection); await using var command = new SqlCommand(sql, connection);
command.Parameters.AddWithValue("@UserAccountId", userAccountId); command.Parameters.AddWithValue("@UserAccountId", userAccountId);
object? result = await command.ExecuteScalarAsync(); object? result = await command.ExecuteScalarAsync();
@@ -289,13 +222,13 @@ WHERE UserAccountId = @UserAccountId;
) )
{ {
const string sql = """ const string sql = """
SELECT 1 SELECT 1
FROM dbo.UserVerification FROM dbo.UserVerification
WHERE UserAccountId = @UserAccountId; WHERE UserAccountId = @UserAccountId;
"""; """;
await using var command = new SqlCommand(sql, connection); await using var command = new SqlCommand(sql, connection);
command.Parameters.AddWithValue("@UserAccountId", userAccountId); command.Parameters.AddWithValue("@UserAccountId", userAccountId);
object? result = await command.ExecuteScalarAsync(); var result = await command.ExecuteScalarAsync();
return result is not null; return result is not null;
} }
@@ -314,18 +247,6 @@ WHERE UserAccountId = @UserAccountId;
await command.ExecuteNonQueryAsync(); await command.ExecuteNonQueryAsync();
} }
private static string BuildUsername(string firstName, string lastName)
{
string username = $"{firstName}.{lastName}".ToLowerInvariant();
return username.Length <= 64 ? username : username[..64];
}
private static string BuildEmail(string firstName, string lastName)
{
string email = $"{firstName}.{lastName}@example.com".ToLowerInvariant();
return email.Length <= 128 ? email : email[..128];
}
private static DateTime GenerateDateOfBirth(Random random) private static DateTime GenerateDateOfBirth(Random random)
{ {
int age = 19 + random.Next(0, 30); int age = 19 + random.Next(0, 30);
@@ -333,4 +254,5 @@ WHERE UserAccountId = @UserAccountId;
int offsetDays = random.Next(0, 365); int offsetDays = random.Next(0, 365);
return baseDate.AddDays(-offsetDays); return baseDate.AddDays(-offsetDays);
} }
}
} }

View File

@@ -2,7 +2,7 @@ namespace DataAccessLayer.Entities;
public class UserAccount public class UserAccount
{ {
public Guid UserAccountID { get; set; } public Guid UserAccountId { get; set; }
public string Username { get; set; } = string.Empty; public string Username { get; set; } = string.Empty;
public string FirstName { get; set; } = string.Empty; public string FirstName { get; set; } = string.Empty;
public string LastName { get; set; } = string.Empty; public string LastName { get; set; } = string.Empty;

View File

@@ -2,8 +2,8 @@ namespace DataAccessLayer.Entities;
public class UserCredential public class UserCredential
{ {
public Guid UserCredentialID { get; set; } public Guid UserCredentialId { get; set; }
public Guid UserAccountID { get; set; } public Guid UserAccountId { get; set; }
public DateTime CreatedAt { get; set; } public DateTime CreatedAt { get; set; }
public DateTime Expiry { get; set; } public DateTime Expiry { get; set; }
public string Hash { get; set; } = string.Empty; public string Hash { get; set; } = string.Empty;

View File

@@ -2,8 +2,8 @@ namespace DataAccessLayer.Entities;
public class UserVerification public class UserVerification
{ {
public Guid UserVerificationID { get; set; } public Guid UserVerificationId { get; set; }
public Guid UserAccountID { get; set; } public Guid UserAccountId { get; set; }
public DateTime VerificationDateTime { get; set; } public DateTime VerificationDateTime { get; set; }
public byte[]? Timer { get; set; } public byte[]? Timer { get; set; }
} }

View File

@@ -1,7 +1,8 @@
using System;
using System.Collections.Generic;
namespace DataAccessLayer
using Microsoft.Data.SqlClient;
namespace DataAccessLayer.Repositories
{ {
public interface IRepository<T> public interface IRepository<T>
where T : class where T : class
@@ -13,5 +14,7 @@ namespace DataAccessLayer
T? GetById(Guid id); T? GetById(Guid id);
void Update(T entity); void Update(T entity);
void Delete(Guid id); void Delete(Guid id);
T MapToEntity(SqlDataReader entity);
} }
} }

View File

@@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using DataAccessLayer.Entities; using DataAccessLayer.Entities;
namespace DataAccessLayer namespace DataAccessLayer.Repositories
{ {
public interface IUserAccountRepository : IRepository<UserAccount> public interface IUserAccountRepository : IRepository<UserAccount>
{ {

View File

@@ -1,30 +1,36 @@
using System;
using System.Collections.Generic;
using DataAccessLayer.Entities; using DataAccessLayer.Entities;
using Microsoft.Data.SqlClient; using Microsoft.Data.SqlClient;
namespace DataAccessLayer namespace DataAccessLayer.Repositories
{ {
public class UserAccountRepository : IUserAccountRepository public class UserAccountRepository : IUserAccountRepository
{ {
private readonly string _connectionString; private readonly string _connectionString = Environment.GetEnvironmentVariable("DB_CONNECTION_STRING")
public UserAccountRepository()
{
// Retrieve the connection string from environment variables
_connectionString =
Environment.GetEnvironmentVariable("DB_CONNECTION_STRING")
?? throw new InvalidOperationException( ?? throw new InvalidOperationException(
"The connection string is not set in the environment variables." "The connection string is not set in the environment variables."
); );
}
public void Add(UserAccount userAccount) public void Add(UserAccount userAccount)
{ {
using SqlConnection connection = new(_connectionString); using SqlConnection connection = new(_connectionString);
using SqlCommand command = new("usp_CreateUserAccount", connection); using SqlCommand command = new("usp_CreateUserAccount", connection);
command.CommandType = System.Data.CommandType.StoredProcedure; command.CommandType = System.Data.CommandType.StoredProcedure;
AddUserAccountCreateParameters(command, userAccount);
command.Parameters.AddWithValue(
"@UserAccountId",
userAccount.UserAccountId
);
command.Parameters.AddWithValue("@Username", userAccount.Username);
command.Parameters.AddWithValue(
"@FirstName",
userAccount.FirstName
);
command.Parameters.AddWithValue("@LastName", userAccount.LastName);
command.Parameters.AddWithValue("@Email", userAccount.Email);
command.Parameters.AddWithValue(
"@DateOfBirth",
userAccount.DateOfBirth
);
connection.Open(); connection.Open();
command.ExecuteNonQuery(); command.ExecuteNonQuery();
} }
@@ -41,7 +47,7 @@ namespace DataAccessLayer
connection.Open(); connection.Open();
using SqlDataReader reader = command.ExecuteReader(); using SqlDataReader reader = command.ExecuteReader();
return reader.Read() ? MapUserAccount(reader) : null; return reader.Read() ? MapToEntity(reader) : null;
} }
public void Update(UserAccount userAccount) public void Update(UserAccount userAccount)
@@ -49,7 +55,25 @@ namespace DataAccessLayer
using SqlConnection connection = new(_connectionString); using SqlConnection connection = new(_connectionString);
using SqlCommand command = new("usp_UpdateUserAccount", connection); using SqlCommand command = new("usp_UpdateUserAccount", connection);
command.CommandType = System.Data.CommandType.StoredProcedure; command.CommandType = System.Data.CommandType.StoredProcedure;
AddUserAccountUpdateParameters(command, userAccount); command.Parameters.AddWithValue(
"@UserAccountId",
userAccount.UserAccountId
);
command.Parameters.AddWithValue("@Username", userAccount.Username);
command.Parameters.AddWithValue(
"@FirstName",
userAccount.FirstName
);
command.Parameters.AddWithValue("@LastName", userAccount.LastName);
command.Parameters.AddWithValue("@Email", userAccount.Email);
command.Parameters.AddWithValue(
"@DateOfBirth",
userAccount.DateOfBirth
);
command.Parameters.AddWithValue(
"@UserAccountId",
userAccount.UserAccountId
);
connection.Open(); connection.Open();
command.ExecuteNonQuery(); command.ExecuteNonQuery();
} }
@@ -64,9 +88,10 @@ namespace DataAccessLayer
command.ExecuteNonQuery(); command.ExecuteNonQuery();
} }
public IEnumerable<UserAccount> GetAll(int? limit, int? offset) public IEnumerable<UserAccount> GetAll(int? limit, int? offset)
{ {
if (limit.HasValue && limit <= 0) if (limit is <= 0)
{ {
throw new ArgumentOutOfRangeException( throw new ArgumentOutOfRangeException(
nameof(limit), nameof(limit),
@@ -110,7 +135,7 @@ namespace DataAccessLayer
List<UserAccount> users = new(); List<UserAccount> users = new();
while (reader.Read()) while (reader.Read())
{ {
users.Add(MapUserAccount(reader)); users.Add(MapToEntity(reader));
} }
return users; return users;
@@ -127,8 +152,8 @@ namespace DataAccessLayer
command.Parameters.AddWithValue("@Username", username); command.Parameters.AddWithValue("@Username", username);
connection.Open(); connection.Open();
using SqlDataReader reader = command.ExecuteReader(); using SqlDataReader? reader = command.ExecuteReader();
return reader.Read() ? MapUserAccount(reader) : null; return reader.Read() ? MapToEntity(reader) : null;
} }
public UserAccount? GetByEmail(string email) public UserAccount? GetByEmail(string email)
@@ -143,48 +168,14 @@ namespace DataAccessLayer
connection.Open(); connection.Open();
using SqlDataReader reader = command.ExecuteReader(); using SqlDataReader reader = command.ExecuteReader();
return reader.Read() ? MapUserAccount(reader) : null; return reader.Read() ? MapToEntity(reader) : null;
} }
private static void AddUserAccountCreateParameters( public UserAccount MapToEntity(SqlDataReader reader)
SqlCommand command,
UserAccount userAccount
)
{
command.Parameters.AddWithValue(
"@UserAccountId",
userAccount.UserAccountID
);
command.Parameters.AddWithValue("@Username", userAccount.Username);
command.Parameters.AddWithValue(
"@FirstName",
userAccount.FirstName
);
command.Parameters.AddWithValue("@LastName", userAccount.LastName);
command.Parameters.AddWithValue("@Email", userAccount.Email);
command.Parameters.AddWithValue(
"@DateOfBirth",
userAccount.DateOfBirth
);
}
private static void AddUserAccountUpdateParameters(
SqlCommand command,
UserAccount userAccount
)
{
AddUserAccountCreateParameters(command, userAccount);
command.Parameters.AddWithValue(
"@UserAccountId",
userAccount.UserAccountID
);
}
private static UserAccount MapUserAccount(SqlDataReader reader)
{ {
return new UserAccount return new UserAccount
{ {
UserAccountID = reader.GetGuid(0), UserAccountId = reader.GetGuid(0),
Username = reader.GetString(1), Username = reader.GetString(1),
FirstName = reader.GetString(2), FirstName = reader.GetString(2),
LastName = reader.GetString(3), LastName = reader.GetString(3),

View File

@@ -4,38 +4,27 @@ using Microsoft.Data.SqlClient;
namespace DataAccessLayer.Sql namespace DataAccessLayer.Sql
{ {
public class DatabaseHelper public class DatabaseHelper(string connectionString)
{ {
private readonly string _connectionString;
public DatabaseHelper(string connectionString)
{
_connectionString = connectionString;
}
public void ExecuteRawSql(string query) public void ExecuteRawSql(string query)
{ {
try try
{ {
using ( using var connection = new SqlConnection(
SqlConnection connection = new SqlConnection( connectionString
_connectionString );
)
)
{
connection.Open(); connection.Open();
using ( using var command = new SqlCommand(query, connection);
SqlCommand command = new SqlCommand(query, connection)
)
{
command.CommandType = CommandType.Text; command.CommandType = CommandType.Text;
using (SqlDataReader reader = command.ExecuteReader()) using var reader = command.ExecuteReader();
{
while (reader.Read()) while (reader.Read())
{ {
for (int i = 0; i < reader.FieldCount; i++) for (var i = 0; i < reader.FieldCount; i++)
{ {
Console.WriteLine( Console.WriteLine(
$"{reader.GetName(i)}: {reader.GetValue(i)}" $"{reader.GetName(i)}: {reader.GetValue(i)}"
@@ -43,9 +32,6 @@ namespace DataAccessLayer.Sql
} }
} }
} }
}
}
}
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine($"An error occurred: {ex.Message}"); Console.WriteLine($"An error occurred: {ex.Message}");

View File

@@ -65,15 +65,15 @@ namespace WebAPI.Controllers
[HttpPost] [HttpPost]
public IActionResult CreateUser([FromBody] UserAccount userAccount) public IActionResult CreateUser([FromBody] UserAccount userAccount)
{ {
if (userAccount.UserAccountID == Guid.Empty) if (userAccount.UserAccountId == Guid.Empty)
{ {
userAccount.UserAccountID = Guid.NewGuid(); userAccount.UserAccountId = Guid.NewGuid();
} }
_userService.Add(userAccount); _userService.Add(userAccount);
return CreatedAtAction( return CreatedAtAction(
nameof(GetUserById), nameof(GetUserById),
new { id = userAccount.UserAccountID }, new { id = userAccount.UserAccountId },
userAccount userAccount
); );
} }
@@ -85,14 +85,14 @@ namespace WebAPI.Controllers
) )
{ {
if ( if (
userAccount.UserAccountID != Guid.Empty userAccount.UserAccountId != Guid.Empty
&& userAccount.UserAccountID != id && userAccount.UserAccountId != id
) )
{ {
return BadRequest("UserAccountID does not match route id."); return BadRequest("UserAccountID does not match route id.");
} }
userAccount.UserAccountID = id; userAccount.UserAccountId = id;
_userService.Update(userAccount); _userService.Update(userAccount);
return NoContent(); return NoContent();
} }

View File

@@ -1,5 +1,6 @@
using BusinessLayer.Services; using BusinessLayer.Services;
using DataAccessLayer; using DataAccessLayer;
using DataAccessLayer.Repositories;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);