using Microsoft.EntityFrameworkCore; using System.Linq.Expressions; using DramaLing.Api.Data; using DramaLing.Api.Contracts.Repositories; namespace DramaLing.Api.Repositories; /// /// 基礎 Repository 實作,提供通用的數據存取邏輯 /// /// 實體類型 public class BaseRepository : IRepository where T : class { protected readonly DramaLingDbContext _context; protected readonly DbSet _dbSet; protected readonly ILogger> _logger; public BaseRepository(DramaLingDbContext context, ILogger> logger) { _context = context ?? throw new ArgumentNullException(nameof(context)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _dbSet = _context.Set(); } #region 查詢操作 public virtual async Task GetByIdAsync(object id) { try { return await _dbSet.FindAsync(id); } catch (Exception ex) { _logger.LogError(ex, "Error getting entity by id: {Id}", id); throw; } } public virtual async Task> GetAllAsync() { try { return await _dbSet.AsNoTracking().ToListAsync(); } catch (Exception ex) { _logger.LogError(ex, "Error getting all entities of type {EntityType}", typeof(T).Name); throw; } } public virtual async Task> FindAsync(Expression> predicate) { try { return await _dbSet.AsNoTracking().Where(predicate).ToListAsync(); } catch (Exception ex) { _logger.LogError(ex, "Error finding entities with predicate for type {EntityType}", typeof(T).Name); throw; } } public virtual async Task FirstOrDefaultAsync(Expression> predicate) { try { return await _dbSet.AsNoTracking().FirstOrDefaultAsync(predicate); } catch (Exception ex) { _logger.LogError(ex, "Error getting first entity with predicate for type {EntityType}", typeof(T).Name); throw; } } public virtual async Task ExistsAsync(Expression> predicate) { try { return await _dbSet.AnyAsync(predicate); } catch (Exception ex) { _logger.LogError(ex, "Error checking entity existence for type {EntityType}", typeof(T).Name); throw; } } public virtual async Task CountAsync(Expression>? predicate = null) { try { return predicate == null ? await _dbSet.CountAsync() : await _dbSet.CountAsync(predicate); } catch (Exception ex) { _logger.LogError(ex, "Error counting entities for type {EntityType}", typeof(T).Name); throw; } } public virtual async Task<(IEnumerable Items, int TotalCount)> GetPagedAsync( int pageNumber, int pageSize, Expression>? filter = null, Func, IOrderedQueryable>? orderBy = null) { try { var query = _dbSet.AsNoTracking(); if (filter != null) query = query.Where(filter); var totalCount = await query.CountAsync(); if (orderBy != null) query = orderBy(query); var items = await query .Skip((pageNumber - 1) * pageSize) .Take(pageSize) .ToListAsync(); return (items, totalCount); } catch (Exception ex) { _logger.LogError(ex, "Error getting paged entities for type {EntityType}, page: {PageNumber}, size: {PageSize}", typeof(T).Name, pageNumber, pageSize); throw; } } #endregion #region 修改操作 public virtual async Task AddAsync(T entity) { try { var result = await _dbSet.AddAsync(entity); return result.Entity; } catch (Exception ex) { _logger.LogError(ex, "Error adding entity of type {EntityType}", typeof(T).Name); throw; } } public virtual async Task> AddRangeAsync(IEnumerable entities) { try { var entityList = entities.ToList(); await _dbSet.AddRangeAsync(entityList); return entityList; } catch (Exception ex) { _logger.LogError(ex, "Error adding entities of type {EntityType}", typeof(T).Name); throw; } } public virtual Task UpdateAsync(T entity) { try { _dbSet.Update(entity); return Task.CompletedTask; } catch (Exception ex) { _logger.LogError(ex, "Error updating entity of type {EntityType}", typeof(T).Name); throw; } } public virtual Task UpdateRangeAsync(IEnumerable entities) { try { _dbSet.UpdateRange(entities); return Task.CompletedTask; } catch (Exception ex) { _logger.LogError(ex, "Error updating entities of type {EntityType}", typeof(T).Name); throw; } } public virtual Task DeleteAsync(T entity) { try { _dbSet.Remove(entity); return Task.CompletedTask; } catch (Exception ex) { _logger.LogError(ex, "Error deleting entity of type {EntityType}", typeof(T).Name); throw; } } public virtual async Task DeleteAsync(object id) { try { var entity = await GetByIdAsync(id); if (entity != null) { _dbSet.Remove(entity); } } catch (Exception ex) { _logger.LogError(ex, "Error deleting entity by id: {Id} of type {EntityType}", id, typeof(T).Name); throw; } } public virtual Task DeleteRangeAsync(IEnumerable entities) { try { _dbSet.RemoveRange(entities); return Task.CompletedTask; } catch (Exception ex) { _logger.LogError(ex, "Error deleting entities of type {EntityType}", typeof(T).Name); throw; } } #endregion #region 工作單元 public virtual async Task SaveChangesAsync() { try { return await _context.SaveChangesAsync(); } catch (Exception ex) { _logger.LogError(ex, "Error saving changes for type {EntityType}", typeof(T).Name); throw; } } #endregion }