149 lines
4.8 KiB
C#
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();
|
|
}
|
|
}
|
|
}
|
|
} |