Files
GenericStuff/DAL/Repositories/ProductRepository.cs
2024-07-14 19:45:34 +07:00

149 lines
4.8 KiB
C#

using System.Text.Json;
using DAL.Database;
using Domain.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Logging;
namespace DAL.Repositories;
public class ProductRepository: IProductRepository
{
private readonly DatabaseContext _db;
private readonly ILogger _logger;
private readonly IDistributedCache _cache;
public ProductRepository(DatabaseContext db, ILogger logger, IDistributedCache cache)
{
_db = db;
_logger = logger;
_cache = cache;
}
public async Task<Product> Get(int id, int cacheLifetime, CancellationToken token)
{
var productCache = await _cache.GetAsync(id.ToString(), token);
var product = new Product();
if(productCache is not null)
product = JsonSerializer.Deserialize<Product>(productCache);
if (product is not null)
return product;
product = await _db.Products.FindAsync(id) ??
throw new KeyNotFoundException("Product not found");
_db.Entry(product).Reference(p => p.Description).Load();
await _cache.SetStringAsync(
product.Id.ToString(),
JsonSerializer.Serialize(product),
new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(cacheLifetime)
}, token);
return product;
}
public async Task<List<Product>> GetAll(int cacheLifeTime, CancellationToken token)
{
var productsCache = await _cache.GetAsync("Products", token);
var products = new List<Product>();
if (productsCache is not null)
products = JsonSerializer.Deserialize<List<Product>> (productsCache);
if(products is not null && products.Count() > 0)
return products;
products = await _db.Products
.Include(p => p.Description)
.ToListAsync(token)
?? throw new NullReferenceException("Database is empty");
await _cache.SetStringAsync("Products",
JsonSerializer.Serialize(products),
new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(cacheLifeTime)
}, token);
return products;
}
public async Task Delete(int id, CancellationToken token)
{
var product = await _db.Products.FindAsync(id) ??
throw new KeyNotFoundException("Product not found");
_db.Products.Remove(product);
await _cache.RemoveAsync(id.ToString(), token);
await _db.SaveChangesAsync();
}
public async Task Update(Product entity, int cacheLifetime, CancellationToken token)
{
var product = await _db.Products.FindAsync(entity.Id) ??
throw new KeyNotFoundException("Product not found");
_db.Entry(product).Reference(p => p.Description).Load();
_db.Entry(product).CurrentValues.SetValues(entity);
_db.Entry(product.Description).CurrentValues.SetValues(entity.Description);
await _cache.RemoveAsync(product.Id.ToString(), token);
await _cache.SetStringAsync(product.Id.ToString(),
JsonSerializer.Serialize(entity),
new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(cacheLifetime)
}, token);
await _db.SaveChangesAsync();
}
public async Task Create(Product entity, int cacheLifeTime, CancellationToken token)
{
using (var transaction = _db.Database.BeginTransaction())
{
try
{
await _db.Products.AddAsync(entity);
await _db.Descriptions.AddAsync(entity.Description);
await _db.SaveChangesAsync();
transaction.Commit();
var products = await _db.Products
.Include(p => p.Description)
.ToListAsync()
?? throw new NullReferenceException("Database is empty");
await _cache.RemoveAsync("Products", token);
await _cache.SetStringAsync("Products",
JsonSerializer.Serialize(products),
new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(cacheLifeTime)
}, token);
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
transaction.Rollback();
throw new Exception(ex.Message);
}
finally
{
transaction.Dispose();
}
}
}
}