Fix db seeding, migration, repository services
This commit is contained in:
parent
872dc1e263
commit
6b87902ca7
22 changed files with 606 additions and 64 deletions
|
@ -3,7 +3,6 @@ namespace CSR.Infrastructure.Persistence;
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using CSR.Infrastructure.Persistence.Configurations;
|
||||
|
||||
|
||||
public class CSRDbContext(DbContextOptions<CSRDbContext> options) : DbContext(options)
|
||||
{
|
||||
public DbSet<User> Users { get; set; }
|
||||
|
@ -23,14 +22,9 @@ public class CSRDbContext(DbContextOptions<CSRDbContext> options) : DbContext(op
|
|||
.WithMany(r => r.Users)
|
||||
.HasForeignKey(u => u.RoleId);
|
||||
|
||||
// --- Seed data --- //
|
||||
|
||||
var adminRole = new Role { Id = 1, Name = "Admin" };
|
||||
var userRole = new Role { Id = 2, Name = "User" };
|
||||
|
||||
modelBuilder.Entity<Role>()
|
||||
.HasData(adminRole, userRole);
|
||||
|
||||
.HasIndex(r => r.Name)
|
||||
.IsUnique();
|
||||
|
||||
base.OnModelCreating(modelBuilder);
|
||||
}
|
||||
|
|
36
CSR.Infrastructure/Persistence/CSRDbContextFactory.cs
Normal file
36
CSR.Infrastructure/Persistence/CSRDbContextFactory.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Design;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace CSR.Infrastructure.Persistence
|
||||
{
|
||||
public class CSRDbContextFactory : IDesignTimeDbContextFactory<CSRDbContext>
|
||||
{
|
||||
public CSRDbContext CreateDbContext(string[] args)
|
||||
{
|
||||
// build configuration.
|
||||
var configuration = new ConfigurationBuilder()
|
||||
.SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), "..", "CSR.WebUI"))
|
||||
.AddJsonFile("appsettings.json", optional: true)
|
||||
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Development"}.json", optional: true)
|
||||
.AddEnvironmentVariables()
|
||||
.AddKeyPerFile("/run/secrets", optional: true)
|
||||
.Build();
|
||||
|
||||
// get the database path
|
||||
var dbPath = configuration["Database:Path"];
|
||||
if (string.IsNullOrEmpty(dbPath))
|
||||
{
|
||||
var folder = Environment.SpecialFolder.LocalApplicationData;
|
||||
var path = Environment.GetFolderPath(folder);
|
||||
dbPath = Path.Join(path, "csr.db");
|
||||
}
|
||||
|
||||
// create DbContextOptions
|
||||
var optionsBuilder = new DbContextOptionsBuilder<CSRDbContext>();
|
||||
optionsBuilder.UseSqlite($"Data Source={dbPath}");
|
||||
|
||||
return new CSRDbContext(optionsBuilder.Options);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,11 +9,9 @@ public class RoleConfiguration : IEntityTypeConfiguration<Role>
|
|||
public void Configure(EntityTypeBuilder<Role> builder)
|
||||
{
|
||||
builder.Property(u => u.Id)
|
||||
.HasColumnName("RoleId")
|
||||
.IsRequired();
|
||||
.HasColumnName("RoleId");
|
||||
|
||||
builder.Property(u => u.Name)
|
||||
.HasColumnName("RoleName")
|
||||
.IsRequired();
|
||||
.HasColumnName("RoleName");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ public class UserConfiguration : IEntityTypeConfiguration<User>
|
|||
public void Configure(EntityTypeBuilder<User> builder)
|
||||
{
|
||||
builder.Property(u => u.PasswordHash)
|
||||
.HasColumnName("Password")
|
||||
.IsRequired();
|
||||
.HasColumnName("Password");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@ public class RoleRepository(CSR.Infrastructure.Persistence.CSRDbContext context)
|
|||
{
|
||||
var roleEntity = new CSR.Infrastructure.Persistence.Role
|
||||
{
|
||||
Id = role.Id,
|
||||
Name = role.Name
|
||||
};
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
namespace Csr.Infrastructure.Persistence.Repositories;
|
||||
namespace CSR.Infrastructure.Persistence.Repositories;
|
||||
|
||||
using CSR.Domain.Entities;
|
||||
using CSR.Application.Interfaces;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
public class UserRepository(CSR.Infrastructure.Persistence.CSRDbContext context) : IUserRepository
|
||||
public class UserRepository(CSRDbContext context) : IUserRepository
|
||||
{
|
||||
private readonly CSR.Infrastructure.Persistence.CSRDbContext _context = context;
|
||||
private readonly CSRDbContext _context = context;
|
||||
|
||||
public async Task<User?> GetByIdAsync(int id)
|
||||
{
|
||||
|
@ -35,23 +35,97 @@ public class UserRepository(CSR.Infrastructure.Persistence.CSRDbContext context)
|
|||
}
|
||||
|
||||
|
||||
public async Task AddAsync(User user)
|
||||
public async Task<User?> GetByUsernameAsync(string username)
|
||||
{
|
||||
var userEntity = new CSR.Infrastructure.Persistence.User
|
||||
var userEntity = await _context.Users
|
||||
.Include(u => u.Role)
|
||||
.SingleOrDefaultAsync(u => u.Username == username);
|
||||
|
||||
if (userEntity == null)
|
||||
{
|
||||
return null; // No entity found, return null domain model
|
||||
}
|
||||
|
||||
var user = User.LoadExisting(
|
||||
userEntity.Id,
|
||||
userEntity.Username,
|
||||
userEntity.Email,
|
||||
userEntity.PasswordHash,
|
||||
userEntity.RoleId,
|
||||
Role.LoadExisting(
|
||||
userEntity.Role.Id,
|
||||
userEntity.Role.Name
|
||||
)
|
||||
);
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
|
||||
public async Task<IEnumerable<User>?> GetAllByRoleIdAsync(int roleId)
|
||||
{
|
||||
var roleEntity = await _context.Roles
|
||||
.Include(r => r.Users)
|
||||
.FirstOrDefaultAsync(r => r.Id == roleId);
|
||||
|
||||
if (roleEntity == null)
|
||||
{
|
||||
return null; // No entity found, return null
|
||||
}
|
||||
|
||||
var users = roleEntity.Users
|
||||
.Select(userEntity => User.LoadExisting(
|
||||
userEntity.Id,
|
||||
userEntity.Username,
|
||||
userEntity.Email,
|
||||
userEntity.PasswordHash,
|
||||
userEntity.RoleId,
|
||||
Role.LoadExisting(
|
||||
userEntity.Role.Id,
|
||||
userEntity.Role.Name
|
||||
)
|
||||
));
|
||||
|
||||
return users;
|
||||
}
|
||||
|
||||
|
||||
public async Task<User?> AddAsync(User user)
|
||||
{
|
||||
var roleEntity = await _context.Roles
|
||||
.SingleOrDefaultAsync(r => r.Id == user.RoleId)
|
||||
?? throw new InvalidOperationException($"Role with ID {user.RoleId} does not exist.");
|
||||
|
||||
var userEntity = new Persistence.User
|
||||
{
|
||||
Username = user.Username,
|
||||
Email = user.Email,
|
||||
PasswordHash = user.PasswordHash,
|
||||
RoleId = user.RoleId,
|
||||
Role = new CSR.Infrastructure.Persistence.Role
|
||||
{
|
||||
Id = user.Role.Id,
|
||||
Name = user.Role.Name
|
||||
}
|
||||
Role = roleEntity
|
||||
};
|
||||
|
||||
_context.Users.Add(userEntity);
|
||||
try
|
||||
{
|
||||
_context.Users.Add(userEntity);
|
||||
}
|
||||
catch (DbUpdateException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
return User.LoadExisting(
|
||||
userEntity.Id,
|
||||
userEntity.Username,
|
||||
userEntity.Email,
|
||||
userEntity.PasswordHash,
|
||||
userEntity.RoleId,
|
||||
Role.LoadExisting(
|
||||
userEntity.Role.Id,
|
||||
userEntity.Role.Name
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
@ -73,7 +147,7 @@ public class UserRepository(CSR.Infrastructure.Persistence.CSRDbContext context)
|
|||
userEntity.Email = user.Email;
|
||||
userEntity.PasswordHash = user.PasswordHash;
|
||||
userEntity.RoleId = user.RoleId;
|
||||
userEntity.Role = new CSR.Infrastructure.Persistence.Role { Id = user.Role.Id, Name = user.Role.Name };
|
||||
userEntity.Role = new Persistence.Role { Id = user.Role.Id, Name = user.Role.Name };
|
||||
|
||||
// Prevent EF from trying to update the Role entity
|
||||
_context.Entry(userEntity.Role).State = EntityState.Unchanged;
|
||||
|
@ -85,18 +159,13 @@ public class UserRepository(CSR.Infrastructure.Persistence.CSRDbContext context)
|
|||
|
||||
public async Task DeleteAsync(int id)
|
||||
{
|
||||
var userEntity = new CSR.Infrastructure.Persistence.User
|
||||
var userEntity = new Persistence.User
|
||||
{
|
||||
Id = id,
|
||||
Username = string.Empty,
|
||||
Email = string.Empty,
|
||||
PasswordHash = string.Empty,
|
||||
RoleId = 0,
|
||||
Role = new CSR.Infrastructure.Persistence.Role
|
||||
{
|
||||
Id = 0,
|
||||
Name = string.Empty
|
||||
}
|
||||
RoleId = 0
|
||||
};
|
||||
|
||||
_context.Users.Remove(userEntity);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue