using DigitalData.Core.Abstractions; using DigitalData.Core.Abstractions.Infrastructure; using Microsoft.EntityFrameworkCore; namespace DigitalData.Core.Infrastructure { /// /// Provides a generic implementation for CRUD (Create, Read, Update, Delete) operations within a given DbContext. /// /// The entity type for which the repository is created. Must be a class. /// The type of the entity's identifier. /// The DbContext type associated with the entity. /// /// This repository abstracts the common database operations, offering an asynchronous API to work with the entity's data. /// It leverages the EF Core's DbContext and DbSet to perform these operations. /// public class CRUDRepository : ICRUDRepository where TEntity : class, IUnique where TDbContext : DbContext { protected readonly TDbContext _dbContext; protected readonly DbSet _dbSet; /// /// Initializes a new instance of the CRUDRepository with the specified DbContext. /// /// The DbContext instance to be used by the repository. public CRUDRepository(TDbContext dbContext) { _dbContext = dbContext; _dbSet = dbContext.Set(); } /// /// Asynchronously creates a new entity in the database. /// /// The entity to be added. /// The created entity, or null if the entity cannot be added public virtual async Task CreateAsync(TEntity entity) { await _dbSet.AddAsync(entity); await _dbContext.SaveChangesAsync(); return entity; } /// /// Asynchronously retrieves an entity by its identifier. /// /// The identifier of the entity to find. /// The entity found, or null if no entity is found with the specified identifier. public virtual async Task ReadByIdAsync(TId id) => await _dbSet.FindAsync(id); /// /// Retrieves all entities of type from the database. /// /// /// This method returns an of all entities in the database. /// The result is not tracked by the context, which improves performance when you only need to read data without making modifications. /// /// An containing all entities of type . protected virtual IQueryable ReadOnly() => _dbSet.AsNoTracking(); /// /// Asynchronously retrieves all entities of type TEntity. /// /// An enumerable of all entities in the database. public virtual async Task> ReadAllAsync() => await ReadOnly().ToListAsync(); /// /// Asynchronously updates an existing entity in the repository. /// /// The entity to be updated. This entity should already exist in the repository. /// A task that represents the asynchronous operation. The task result contains a boolean value that indicates whether the update operation was successful. Returns true if one or more entities were successfully updated; otherwise, false. public virtual async Task UpdateAsync(TEntity entity) { _dbContext.Entry(entity).State = EntityState.Modified; var results = await _dbContext.SaveChangesAsync(); return results > 0; } /// /// Asynchronously deletes an entity from the database. /// /// The entity to be deleted. /// If entity is deleted, return true othwerwise return false. public virtual async Task DeleteAsync(TEntity entity) { _dbSet.Remove(entity); var result = await _dbContext.SaveChangesAsync(); return result > 0; } /// /// Asynchronously counts all entities in the repository. /// /// The total number of entities in the repository. public virtual async Task CountAsync() => await _dbSet.CountAsync(); } }