📋 Issue Summary
The current data layer architecture lacks consistency and standardization. We need to implement a BaseEntity class and BaseRepository pattern to establish a solid foundation for all domain entities and data access operations.
🎯 Current Problems
1. Inconsistent Entity Structure
- All entities use
int IDs instead of long for better scalability
- No audit trail fields (CreatedAt, UpdatedAt, CreatedBy, UpdatedBy)
- Each entity has its own ID property without inheritance
- Missing standardized soft delete pattern across entities
2. Repository Code Duplication
- Only
AuthorRepository exists with repetitive CRUD operations
- No generic base repository for common operations
- Future entities will require duplicate CRUD implementations
- No standardized approach for data access patterns
3. Missing Audit Capabilities
- No tracking of who created/modified records
- No timestamps for data change tracking
- Missing compliance and accountability features
🚀 Proposed Solution
BaseEntity Class Implementation
Create a BaseEntity abstract class in Data/Models/ with the following properties:
public abstract class BaseEntity
{
public long Id { get; set; }
public DateTimeOffset CreatedAt { get; set; }
public DateTimeOffset UpdatedAt { get; set; }
public string? CreatedBy { get; set; }
public string? UpdatedBy { get; set; }
}
Key Benefits:
- Long ID: Better scalability for high-volume applications
- DateTimeOffset: Timezone-aware timestamps for global applications
- Audit Fields: Track who and when made changes
- Nullable User Fields: Support anonymous/system operations
BaseRepository Interface & Implementation
Create generic repository pattern in Service/Interface/ and Service/Implement/:
public interface IBaseRepository<TEntity> where TEntity : BaseEntity
{
// Read Operations
Task<TEntity?> GetByIdAsync(long id, CancellationToken ct = default);
Task<IEnumerable<TEntity>> GetAllAsync(CancellationToken ct = default);
Task<IEnumerable<TEntity>> GetPagedAsync(int page, int pageSize, CancellationToken ct = default);
// Write Operations
Task<TEntity> AddAsync(TEntity entity, CancellationToken ct = default);
Task<TEntity> UpdateAsync(TEntity entity, CancellationToken ct = default);
Task DeleteAsync(long id, CancellationToken ct = default);
Task<bool> ExistsAsync(long id, CancellationToken ct = default);
// Bulk Operations
Task AddRangeAsync(IEnumerable<TEntity> entities, CancellationToken ct = default);
Task UpdateRangeAsync(IEnumerable<TEntity> entities, CancellationToken ct = default);
Task DeleteRangeAsync(IEnumerable<long> ids, CancellationToken ct = default);
}
📋 Implementation Tasks
Phase 1: Core Infrastructure
Phase 2: Entity Migration
Phase 3: Repository Refactoring
Phase 4: Database Migration
Phase 5: Application Updates
🔧 Technical Considerations
Entity Framework Configuration
public override int SaveChanges()
{
UpdateAuditFields();
return base.SaveChanges();
}
private void UpdateAuditFields()
{
var entries = ChangeTracker.Entries<BaseEntity>();
var currentUser = _httpContextAccessor.HttpContext?.User?.Identity?.Name;
var now = DateTimeOffset.UtcNow;
foreach (var entry in entries)
{
switch (entry.State)
{
case EntityState.Added:
entry.Entity.CreatedAt = now;
entry.Entity.CreatedBy = currentUser;
entry.Entity.UpdatedAt = now;
entry.Entity.UpdatedBy = currentUser;
break;
case EntityState.Modified:
entry.Entity.UpdatedAt = now;
entry.Entity.UpdatedBy = currentUser;
break;
}
}
}
Backward Compatibility
- Plan migration strategy for existing data
- Consider creating database backup before major changes
- Implement gradual rollout approach
- Update existing API consumers about ID type changes
Performance Considerations
- Use appropriate indexing for audit fields
- Consider soft delete implementation in BaseEntity
- Optimize queries for common filtering patterns
- Plan for audit log table if detailed history needed
🎯 Expected Benefits
- Consistency: Standardized entity structure across application
- DRY Principle: Eliminate repository code duplication
- Maintainability: Centralized data access patterns
- Scalability: Long IDs support high-volume growth
- Auditability: Built-in change tracking and accountability
- Developer Experience: Faster development of new entities
📚 References
- Current Entities:
Data/Models/Book.cs, Author.cs, Category.cs, Keyword.cs
- Existing Repository:
Service/Implement/AuthorRepository.cs
- Service Registration:
Tools/ExtentionMethod/AddServiceExtentionMethod.cs
- EF Configurations:
Data/Configuration/ folder
- Architecture Guidelines:
.github/copilot-instructions.md
🏷️ Labels
enhancement architecture data-layer technical-debt repository-pattern
Priority: High - This foundational change will impact all future development
Effort: Large - Requires careful planning and migration strategy
Impact: High - Improves code quality, maintainability, and developer productivity
📋 Issue Summary
The current data layer architecture lacks consistency and standardization. We need to implement a BaseEntity class and BaseRepository pattern to establish a solid foundation for all domain entities and data access operations.
🎯 Current Problems
1. Inconsistent Entity Structure
intIDs instead oflongfor better scalability2. Repository Code Duplication
AuthorRepositoryexists with repetitive CRUD operations3. Missing Audit Capabilities
🚀 Proposed Solution
BaseEntity Class Implementation
Create a
BaseEntityabstract class inData/Models/with the following properties:Key Benefits:
BaseRepository Interface & Implementation
Create generic repository pattern in
Service/Interface/andService/Implement/:📋 Implementation Tasks
Phase 1: Core Infrastructure
BaseEntityabstract class inData/Models/BaseEntity.csIBaseRepository<T>interface inService/Interface/IBaseRepository.csBaseRepository<T>implementation inService/Implement/BaseRepository.csBaseRepositoryinTools/ExtentionMethod/AddServiceExtentionMethod.csPhase 2: Entity Migration
Bookentity to inherit fromBaseEntityAuthorentity to inherit fromBaseEntityCategoryentity to inherit fromBaseEntityKeywordentity to inherit fromBaseEntityBookAuthor,BookKeyword,BookRelation) for BaseEntity needsPhase 3: Repository Refactoring
IAuthorRepositoryto inherit fromIBaseRepository<Author>AuthorRepositoryto inherit fromBaseRepository<Author>Phase 4: Database Migration
int→long)Data/Configuration/Phase 5: Application Updates
longIDslongIDslongID parameters🔧 Technical Considerations
Entity Framework Configuration
Backward Compatibility
Performance Considerations
🎯 Expected Benefits
📚 References
Data/Models/Book.cs,Author.cs,Category.cs,Keyword.csService/Implement/AuthorRepository.csTools/ExtentionMethod/AddServiceExtentionMethod.csData/Configuration/folder.github/copilot-instructions.md🏷️ Labels
enhancementarchitecturedata-layertechnical-debtrepository-patternPriority: High - This foundational change will impact all future development
Effort: Large - Requires careful planning and migration strategy
Impact: High - Improves code quality, maintainability, and developer productivity