Good structure so far

This commit is contained in:
lumijiez
2025-05-04 23:42:28 +03:00
parent e001ea67a3
commit b466a39e89
22 changed files with 466 additions and 335 deletions

View File

@@ -12,80 +12,69 @@ public class ProductGroupRepository(ApplicationDbContext dbContext, IMapper mapp
private readonly ApplicationDbContext _dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext));
private readonly IMapper _mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
public async Task<ProductGroup?> GetByIdAsync(Guid id, CancellationToken cancellationToken = default)
public async Task<ProductGroup?> GetByIdAsync(Guid id, bool includeRelations = false, CancellationToken cancellationToken = default)
{
var dbEntity = await _dbContext.Set<ProductGroupDbEntity>()
.Include(g => g.Types)
.FirstOrDefaultAsync(g => g.Id == id, cancellationToken);
IQueryable<ProductGroupDbEntity> query = _dbContext.ProductGroups;
return dbEntity != null ? _mapper.Map<ProductGroup>(dbEntity) : null;
if (includeRelations) query = query.Include(g => g.Types);
var dbEntity = await query.FirstOrDefaultAsync(g => g.Id == id, cancellationToken);
return dbEntity == null ? null : _mapper.Map<ProductGroup>(dbEntity);
}
public async Task<IEnumerable<ProductGroup>> GetAllAsync(CancellationToken cancellationToken = default)
public async Task<IEnumerable<ProductGroup>> GetAllAsync(bool includeRelations = false, CancellationToken cancellationToken = default)
{
var dbEntities = await _dbContext.Set<ProductGroupDbEntity>()
.Include(g => g.Types)
.ToListAsync(cancellationToken);
IQueryable<ProductGroupDbEntity> query = _dbContext.ProductGroups;
if (includeRelations) query = query.Include(g => g.Types);
var dbEntities = await query.ToListAsync(cancellationToken);
return _mapper.Map<IEnumerable<ProductGroup>>(dbEntities);
}
public async Task<ProductGroup> AddAsync(ProductGroup group, CancellationToken cancellationToken = default)
{
var dbEntity = _mapper.Map<ProductGroupDbEntity>(group);
_dbContext.ProductGroups.Add(dbEntity);
await _dbContext.SaveChangesAsync(cancellationToken);
return _mapper.Map<ProductGroup>(dbEntity);
}
public async Task<ProductGroup> UpdateAsync(ProductGroup group, CancellationToken cancellationToken = default)
{
var existingEntity = await _dbContext.ProductGroups
.Include(g => g.Types)
.FirstOrDefaultAsync(g => g.Id == group.Id, cancellationToken);
if (existingEntity == null) throw new KeyNotFoundException($"ProductGroup with ID {group.Id} not found");
_mapper.Map(group, existingEntity);
existingEntity.UpdatedAt = DateTime.UtcNow;
await _dbContext.SaveChangesAsync(cancellationToken);
return _mapper.Map<ProductGroup>(existingEntity);
}
public async Task<bool> DeleteAsync(Guid id, CancellationToken cancellationToken = default)
{
var entity = await _dbContext.ProductGroups.FindAsync([id], cancellationToken);
if (entity == null) return false;
_dbContext.ProductGroups.Remove(entity);
await _dbContext.SaveChangesAsync(cancellationToken);
return true;
}
public async Task<bool> ExistsAsync(Guid id, CancellationToken cancellationToken = default)
{
return await _dbContext.Set<ProductGroupDbEntity>()
.AnyAsync(g => g.Id == id, cancellationToken);
}
public async Task AddAsync(ProductGroup productGroup, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(productGroup);
var dbEntity = _mapper.Map<ProductGroupDbEntity>(productGroup);
await _dbContext.Set<ProductGroupDbEntity>().AddAsync(dbEntity, cancellationToken);
await _dbContext.SaveChangesAsync(cancellationToken);
}
public async Task UpdateAsync(ProductGroup productGroup, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(productGroup);
var dbEntity = await _dbContext.Set<ProductGroupDbEntity>()
.Include(g => g.Types)
.FirstOrDefaultAsync(g => g.Id == productGroup.Id, cancellationToken);
if (dbEntity == null)
throw new KeyNotFoundException($"ProductGroup with ID {productGroup.Id} not found");
_mapper.Map(productGroup, dbEntity);
var existingTypeIds = dbEntity.Types.Select(t => t.Id).ToList();
var updatedTypeIds = productGroup.Types.Select(t => t.Id).ToList();
var typesToRemove = dbEntity.Types.Where(t => !updatedTypeIds.Contains(t.Id)).ToList();
foreach (var type in typesToRemove)
{
dbEntity.Types.Remove(type);
}
foreach (var type in productGroup.Types)
{
if (existingTypeIds.Contains(type.Id)) continue;
var newType = _mapper.Map<ProductTypeDbEntity>(type);
dbEntity.Types.Add(newType);
}
await _dbContext.SaveChangesAsync(cancellationToken);
}
public async Task DeleteAsync(Guid id, CancellationToken cancellationToken = default)
{
var dbEntity = await _dbContext.Set<ProductGroupDbEntity>()
.FindAsync([id], cancellationToken);
if (dbEntity == null)
return;
_dbContext.Set<ProductGroupDbEntity>().Remove(dbEntity);
await _dbContext.SaveChangesAsync(cancellationToken);
return await _dbContext.ProductGroups.AnyAsync(g => g.Id == id, cancellationToken);
}
}

View File

@@ -12,89 +12,108 @@ public class ProductRepository(ApplicationDbContext dbContext, IMapper mapper) :
private readonly ApplicationDbContext _dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext));
private readonly IMapper _mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
public async Task<Product?> GetByIdAsync(Guid id, CancellationToken cancellationToken = default)
public async Task<Product?> GetByIdAsync(Guid id, bool includeRelations = false, CancellationToken cancellationToken = default)
{
var dbEntity = await _dbContext.Set<ProductDbEntity>()
.Include(p => p.Variants)
.FirstOrDefaultAsync(p => p.Id == id, cancellationToken);
IQueryable<ProductDbEntity> query = _dbContext.Products;
return dbEntity != null ? _mapper.Map<Product>(dbEntity) : null;
if (includeRelations)
{
query = query
.Include(p => p.Type)
.ThenInclude(t => t.Group)
.Include(p => p.Variants);
}
var dbEntity = await query.FirstOrDefaultAsync(p => p.Id == id, cancellationToken);
return dbEntity == null ? null : _mapper.Map<Product>(dbEntity);
}
public async Task<IEnumerable<Product>> GetAllAsync(CancellationToken cancellationToken = default)
public async Task<IEnumerable<Product>> GetAllAsync(bool includeRelations = false, CancellationToken cancellationToken = default)
{
var dbEntities = await _dbContext.Set<ProductDbEntity>()
.Include(p => p.Variants)
.ToListAsync(cancellationToken);
IQueryable<ProductDbEntity> query = _dbContext.Products;
if (includeRelations)
{
query = query
.Include(p => p.Type)
.ThenInclude(t => t.Group)
.Include(p => p.Variants);
}
var dbEntities = await query.ToListAsync(cancellationToken);
return _mapper.Map<IEnumerable<Product>>(dbEntities);
}
public async Task<IEnumerable<Product>> GetByTypeIdAsync(Guid typeId, CancellationToken cancellationToken = default)
public async Task<IEnumerable<Product>> GetByTypeIdAsync(Guid typeId, bool includeRelations = false, CancellationToken cancellationToken = default)
{
var dbEntities = await _dbContext.Set<ProductDbEntity>()
.Include(p => p.Variants)
.Where(p => p.TypeId == typeId)
.ToListAsync(cancellationToken);
var query = _dbContext.Products.Where(p => p.TypeId == typeId);
if (includeRelations)
{
query = query
.Include(p => p.Type)
.ThenInclude(t => t.Group)
.Include(p => p.Variants);
}
var dbEntities = await query.ToListAsync(cancellationToken);
return _mapper.Map<IEnumerable<Product>>(dbEntities);
}
public async Task<Product> AddAsync(Product product, CancellationToken cancellationToken = default)
{
var dbEntity = _mapper.Map<ProductDbEntity>(product);
dbEntity.Type = await _dbContext.ProductTypes.FindAsync([product.TypeId], cancellationToken)
?? throw new InvalidOperationException($"ProductType with ID {product.TypeId} not found");
_dbContext.Products.Add(dbEntity);
await _dbContext.SaveChangesAsync(cancellationToken);
return _mapper.Map<Product>(dbEntity);
}
public async Task<Product> UpdateAsync(Product product, CancellationToken cancellationToken = default)
{
var existingEntity = await _dbContext.Products
.Include(p => p.Variants)
.FirstOrDefaultAsync(p => p.Id == product.Id, cancellationToken);
if (existingEntity == null) throw new KeyNotFoundException($"Product with ID {product.Id} not found");
_mapper.Map(product, existingEntity);
if (existingEntity.TypeId != product.TypeId)
{
existingEntity.Type = await _dbContext.ProductTypes.FindAsync([product.TypeId], cancellationToken)
?? throw new InvalidOperationException($"ProductType with ID {product.TypeId} not found");
existingEntity.TypeId = product.TypeId;
}
existingEntity.UpdatedAt = DateTime.UtcNow;
await _dbContext.SaveChangesAsync(cancellationToken);
return _mapper.Map<Product>(existingEntity);
}
public async Task<bool> DeleteAsync(Guid id, CancellationToken cancellationToken = default)
{
var entity = await _dbContext.Products.FindAsync([id], cancellationToken);
if (entity == null) return false;
_dbContext.Products.Remove(entity);
await _dbContext.SaveChangesAsync(cancellationToken);
return true;
}
public async Task<bool> ExistsAsync(Guid id, CancellationToken cancellationToken = default)
{
return await _dbContext.Set<ProductDbEntity>()
.AnyAsync(p => p.Id == id, cancellationToken);
}
public async Task AddAsync(Product product, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(product);
var dbEntity = _mapper.Map<ProductDbEntity>(product);
await _dbContext.Set<ProductDbEntity>().AddAsync(dbEntity, cancellationToken);
await _dbContext.SaveChangesAsync(cancellationToken);
}
public async Task UpdateAsync(Product product, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(product);
var dbEntity = await _dbContext.Set<ProductDbEntity>()
.Include(p => p.Variants)
.FirstOrDefaultAsync(p => p.Id == product.Id, cancellationToken);
if (dbEntity == null)
throw new KeyNotFoundException($"Product with ID {product.Id} not found");
_mapper.Map(product, dbEntity);
var existingVariantIds = dbEntity.Variants.Select(v => v.Id).ToList();
var updatedVariantIds = product.Variants.Select(v => v.Id).ToList();
var variantsToRemove = dbEntity.Variants.Where(v => !updatedVariantIds.Contains(v.Id)).ToList();
foreach (var variant in variantsToRemove)
{
dbEntity.Variants.Remove(variant);
}
foreach (var variant in product.Variants)
{
if (existingVariantIds.Contains(variant.Id)) continue;
var newVariant = _mapper.Map<ProductVariantDbEntity>(variant);
dbEntity.Variants.Add(newVariant);
}
await _dbContext.SaveChangesAsync(cancellationToken);
}
public async Task DeleteAsync(Guid id, CancellationToken cancellationToken = default)
{
var dbEntity = await _dbContext.Set<ProductDbEntity>()
.FindAsync([id], cancellationToken);
if (dbEntity == null) return;
_dbContext.Set<ProductDbEntity>().Remove(dbEntity);
await _dbContext.SaveChangesAsync(cancellationToken);
return await _dbContext.Products.AnyAsync(p => p.Id == id, cancellationToken);
}
}

View File

@@ -12,69 +12,101 @@ public class ProductTypeRepository(ApplicationDbContext dbContext, IMapper mappe
private readonly ApplicationDbContext _dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext));
private readonly IMapper _mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
public async Task<ProductType?> GetByIdAsync(Guid id, CancellationToken cancellationToken = default)
public async Task<ProductType?> GetByIdAsync(Guid id, bool includeRelations = false, CancellationToken cancellationToken = default)
{
var dbEntity = await _dbContext.Set<ProductTypeDbEntity>()
.FirstOrDefaultAsync(t => t.Id == id, cancellationToken);
IQueryable<ProductTypeDbEntity> query = _dbContext.ProductTypes;
return dbEntity != null ? _mapper.Map<ProductType>(dbEntity) : null;
if (includeRelations)
{
query = query
.Include(t => t.Group)
.Include(t => t.Products);
}
var dbEntity = await query.FirstOrDefaultAsync(t => t.Id == id, cancellationToken);
return dbEntity == null ? null : _mapper.Map<ProductType>(dbEntity);
}
public async Task<IEnumerable<ProductType>> GetAllAsync(CancellationToken cancellationToken = default)
public async Task<IEnumerable<ProductType>> GetAllAsync(bool includeRelations = false, CancellationToken cancellationToken = default)
{
var dbEntities = await _dbContext.Set<ProductTypeDbEntity>()
.ToListAsync(cancellationToken);
IQueryable<ProductTypeDbEntity> query = _dbContext.ProductTypes;
if (includeRelations)
{
query = query
.Include(t => t.Group)
.Include(t => t.Products);
}
var dbEntities = await query.ToListAsync(cancellationToken);
return _mapper.Map<IEnumerable<ProductType>>(dbEntities);
}
public async Task<IEnumerable<ProductType>> GetByGroupIdAsync(Guid groupId, CancellationToken cancellationToken = default)
{
var dbEntities = await _dbContext.Set<ProductTypeDbEntity>()
var dbEntities = await _dbContext.ProductTypes
.Where(t => t.GroupId == groupId)
.ToListAsync(cancellationToken);
return _mapper.Map<IEnumerable<ProductType>>(dbEntities);
}
public async Task<ProductType> AddAsync(ProductType type, CancellationToken cancellationToken = default)
{
var dbEntity = _mapper.Map<ProductTypeDbEntity>(type);
dbEntity.Group = await _dbContext.ProductGroups.FindAsync([type.GroupId], cancellationToken)
?? throw new InvalidOperationException($"ProductGroup with ID {type.GroupId} not found");
_dbContext.ProductTypes.Add(dbEntity);
await _dbContext.SaveChangesAsync(cancellationToken);
return _mapper.Map<ProductType>(dbEntity);
}
public async Task<ProductType> UpdateAsync(ProductType type, CancellationToken cancellationToken = default)
{
var existingEntity = await _dbContext.ProductTypes
.Include(t => t.Products)
.FirstOrDefaultAsync(t => t.Id == type.Id, cancellationToken);
if (existingEntity == null) throw new KeyNotFoundException($"ProductType with ID {type.Id} not found");
_mapper.Map(type, existingEntity);
if (existingEntity.GroupId != type.GroupId)
{
existingEntity.Group = await _dbContext.ProductGroups.FindAsync([type.GroupId], cancellationToken)
?? throw new InvalidOperationException($"ProductGroup with ID {type.GroupId} not found");
existingEntity.GroupId = type.GroupId;
}
existingEntity.UpdatedAt = DateTime.UtcNow;
await _dbContext.SaveChangesAsync(cancellationToken);
return _mapper.Map<ProductType>(existingEntity);
}
public async Task<bool> DeleteAsync(Guid id, CancellationToken cancellationToken = default)
{
var entity = await _dbContext.ProductTypes.FindAsync([id], cancellationToken);
if (entity == null)
{
return false;
}
_dbContext.ProductTypes.Remove(entity);
await _dbContext.SaveChangesAsync(cancellationToken);
return true;
}
public async Task<bool> ExistsAsync(Guid id, CancellationToken cancellationToken = default)
{
return await _dbContext.Set<ProductTypeDbEntity>()
.AnyAsync(t => t.Id == id, cancellationToken);
}
public async Task AddAsync(ProductType productType, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(productType);
var dbEntity = _mapper.Map<ProductTypeDbEntity>(productType);
await _dbContext.Set<ProductTypeDbEntity>().AddAsync(dbEntity, cancellationToken);
await _dbContext.SaveChangesAsync(cancellationToken);
}
public async Task UpdateAsync(ProductType productType, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(productType);
var dbEntity = await _dbContext.Set<ProductTypeDbEntity>()
.FirstOrDefaultAsync(t => t.Id == productType.Id, cancellationToken);
if (dbEntity == null)
throw new KeyNotFoundException($"ProductType with ID {productType.Id} not found");
_mapper.Map(productType, dbEntity);
await _dbContext.SaveChangesAsync(cancellationToken);
}
public async Task DeleteAsync(Guid id, CancellationToken cancellationToken = default)
{
var dbEntity = await _dbContext.Set<ProductTypeDbEntity>()
.FindAsync([id], cancellationToken);
if (dbEntity == null)
return;
_dbContext.Set<ProductTypeDbEntity>().Remove(dbEntity);
await _dbContext.SaveChangesAsync(cancellationToken);
return await _dbContext.ProductTypes.AnyAsync(t => t.Id == id, cancellationToken);
}
}

View File

@@ -12,61 +12,91 @@ public class ProductVariantRepository(ApplicationDbContext dbContext, IMapper ma
private readonly ApplicationDbContext _dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext));
private readonly IMapper _mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
public async Task<ProductVariant?> GetByIdAsync(Guid id, CancellationToken cancellationToken = default)
public async Task<ProductVariant?> GetByIdAsync(Guid id, bool includeRelations = false, CancellationToken cancellationToken = default)
{
var dbEntity = await _dbContext.Set<ProductVariantDbEntity>()
.FirstOrDefaultAsync(v => v.Id == id, cancellationToken);
IQueryable<ProductVariantDbEntity> query = _dbContext.ProductVariants;
return dbEntity != null ? _mapper.Map<ProductVariant>(dbEntity) : null;
if (includeRelations)
query = query.Include(v => v.Product)
.ThenInclude(p => p.Type);
var dbEntity = await query.FirstOrDefaultAsync(v => v.Id == id, cancellationToken);
return dbEntity == null ? null : _mapper.Map<ProductVariant>(dbEntity);
}
public async Task<IEnumerable<ProductVariant>> GetByProductIdAsync(Guid productId, CancellationToken cancellationToken = default)
public async Task<IEnumerable<ProductVariant>> GetAllAsync(bool includeRelations = false, CancellationToken cancellationToken = default)
{
var dbEntities = await _dbContext.Set<ProductVariantDbEntity>()
.Where(v => v.ProductId == productId)
.ToListAsync(cancellationToken);
IQueryable<ProductVariantDbEntity> query = _dbContext.ProductVariants;
if (includeRelations)
query = query.Include(v => v.Product)
.ThenInclude(p => p.Type);
var dbEntities = await query.ToListAsync(cancellationToken);
return _mapper.Map<IEnumerable<ProductVariant>>(dbEntities);
}
public async Task<IEnumerable<ProductVariant>> GetByProductIdAsync(Guid productId, CancellationToken cancellationToken = default)
{
var dbEntities = await _dbContext.ProductVariants
.Where(v => v.ProductId == productId)
.ToListAsync(cancellationToken);
return _mapper.Map<IEnumerable<ProductVariant>>(dbEntities);
}
public async Task<ProductVariant> AddAsync(ProductVariant variant, CancellationToken cancellationToken = default)
{
var dbEntity = _mapper.Map<ProductVariantDbEntity>(variant);
dbEntity.Product = await _dbContext.Products.FindAsync([variant.ProductId], cancellationToken)
?? throw new InvalidOperationException($"Product with ID {variant.ProductId} not found");
_dbContext.ProductVariants.Add(dbEntity);
await _dbContext.SaveChangesAsync(cancellationToken);
return _mapper.Map<ProductVariant>(dbEntity);
}
public async Task<ProductVariant> UpdateAsync(ProductVariant variant, CancellationToken cancellationToken = default)
{
var existingEntity = await _dbContext.ProductVariants
.FindAsync([variant.Id], cancellationToken);
if (existingEntity == null) throw new KeyNotFoundException($"ProductVariant with ID {variant.Id} not found");
_mapper.Map(variant, existingEntity);
if (existingEntity.ProductId != variant.ProductId)
{
existingEntity.Product = await _dbContext.Products.FindAsync([variant.ProductId], cancellationToken)
?? throw new InvalidOperationException($"Product with ID {variant.ProductId} not found");
existingEntity.ProductId = variant.ProductId;
}
existingEntity.UpdatedAt = DateTime.UtcNow;
await _dbContext.SaveChangesAsync(cancellationToken);
return _mapper.Map<ProductVariant>(existingEntity);
}
public async Task<bool> DeleteAsync(Guid id, CancellationToken cancellationToken = default)
{
var entity = await _dbContext.ProductVariants.FindAsync([id], cancellationToken);
if (entity == null) return false;
_dbContext.ProductVariants.Remove(entity);
await _dbContext.SaveChangesAsync(cancellationToken);
return true;
}
public async Task<bool> ExistsAsync(Guid id, CancellationToken cancellationToken = default)
{
return await _dbContext.Set<ProductVariantDbEntity>()
.AnyAsync(v => v.Id == id, cancellationToken);
}
public async Task AddAsync(ProductVariant productVariant, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(productVariant);
var dbEntity = _mapper.Map<ProductVariantDbEntity>(productVariant);
await _dbContext.Set<ProductVariantDbEntity>().AddAsync(dbEntity, cancellationToken);
await _dbContext.SaveChangesAsync(cancellationToken);
}
public async Task UpdateAsync(ProductVariant productVariant, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(productVariant);
var dbEntity = await _dbContext.Set<ProductVariantDbEntity>()
.FirstOrDefaultAsync(v => v.Id == productVariant.Id, cancellationToken);
if (dbEntity == null)
throw new KeyNotFoundException($"ProductVariant with ID {productVariant.Id} not found");
_mapper.Map(productVariant, dbEntity);
await _dbContext.SaveChangesAsync(cancellationToken);
}
public async Task DeleteAsync(Guid id, CancellationToken cancellationToken = default)
{
var dbEntity = await _dbContext.Set<ProductVariantDbEntity>()
.FindAsync([id], cancellationToken);
if (dbEntity == null)
return;
_dbContext.Set<ProductVariantDbEntity>().Remove(dbEntity);
await _dbContext.SaveChangesAsync(cancellationToken);
return await _dbContext.ProductVariants.AnyAsync(v => v.Id == id, cancellationToken);
}
}