first commit
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using MyNewProjectName.Domain.Entities;
|
||||
|
||||
namespace MyNewProjectName.Infrastructure.Persistence.Configurations;
|
||||
|
||||
/// <summary>
|
||||
/// Entity configuration for SampleEntity
|
||||
/// </summary>
|
||||
public class SampleEntityConfiguration : IEntityTypeConfiguration<SampleEntity>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<SampleEntity> builder)
|
||||
{
|
||||
builder.ToTable("Samples");
|
||||
|
||||
builder.HasKey(e => e.Id);
|
||||
|
||||
builder.Property(e => e.Name)
|
||||
.IsRequired()
|
||||
.HasMaxLength(200);
|
||||
|
||||
builder.Property(e => e.Description)
|
||||
.HasMaxLength(1000);
|
||||
|
||||
builder.Property(e => e.CreatedBy)
|
||||
.HasMaxLength(100);
|
||||
|
||||
builder.Property(e => e.UpdatedBy)
|
||||
.HasMaxLength(100);
|
||||
|
||||
// Index for common queries
|
||||
builder.HasIndex(e => e.Name);
|
||||
builder.HasIndex(e => e.IsActive);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using MyNewProjectName.Domain.Common;
|
||||
using MyNewProjectName.Domain.Entities;
|
||||
using System.Reflection;
|
||||
|
||||
namespace MyNewProjectName.Infrastructure.Persistence.Context;
|
||||
|
||||
/// <summary>
|
||||
/// Application database context
|
||||
/// </summary>
|
||||
public class ApplicationDbContext : DbContext
|
||||
{
|
||||
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
|
||||
: base(options)
|
||||
{
|
||||
}
|
||||
|
||||
public DbSet<SampleEntity> Samples => Set<SampleEntity>();
|
||||
|
||||
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
foreach (var entry in ChangeTracker.Entries<AuditableEntity>())
|
||||
{
|
||||
switch (entry.State)
|
||||
{
|
||||
case EntityState.Added:
|
||||
entry.Entity.CreatedAt = DateTime.UtcNow;
|
||||
break;
|
||||
|
||||
case EntityState.Modified:
|
||||
entry.Entity.UpdatedAt = DateTime.UtcNow;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return await base.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
|
||||
|
||||
base.OnModelCreating(modelBuilder);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
using System.Linq.Expressions;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using MyNewProjectName.Domain.Common;
|
||||
using MyNewProjectName.Domain.Interfaces;
|
||||
using MyNewProjectName.Infrastructure.Persistence.Context;
|
||||
|
||||
namespace MyNewProjectName.Infrastructure.Persistence.Repositories;
|
||||
|
||||
/// <summary>
|
||||
/// Generic repository implementation
|
||||
/// </summary>
|
||||
public class Repository<T> : IRepository<T> where T : BaseEntity
|
||||
{
|
||||
protected readonly ApplicationDbContext _context;
|
||||
protected readonly DbSet<T> _dbSet;
|
||||
|
||||
public Repository(ApplicationDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
_dbSet = context.Set<T>();
|
||||
}
|
||||
|
||||
public virtual async Task<T?> GetByIdAsync(Guid id, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await _dbSet.FindAsync(new object[] { id }, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task<IEnumerable<T>> GetAllAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await _dbSet.ToListAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task<IEnumerable<T>> FindAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await _dbSet.Where(predicate).ToListAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task<T?> FirstOrDefaultAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await _dbSet.FirstOrDefaultAsync(predicate, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task<bool> AnyAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await _dbSet.AnyAsync(predicate, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task<int> CountAsync(Expression<Func<T, bool>>? predicate = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (predicate == null)
|
||||
return await _dbSet.CountAsync(cancellationToken);
|
||||
|
||||
return await _dbSet.CountAsync(predicate, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task AddAsync(T entity, CancellationToken cancellationToken = default)
|
||||
{
|
||||
await _dbSet.AddAsync(entity, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual async Task AddRangeAsync(IEnumerable<T> entities, CancellationToken cancellationToken = default)
|
||||
{
|
||||
await _dbSet.AddRangeAsync(entities, cancellationToken);
|
||||
}
|
||||
|
||||
public virtual void Update(T entity)
|
||||
{
|
||||
_dbSet.Attach(entity);
|
||||
_context.Entry(entity).State = EntityState.Modified;
|
||||
}
|
||||
|
||||
public virtual void UpdateRange(IEnumerable<T> entities)
|
||||
{
|
||||
_dbSet.AttachRange(entities);
|
||||
foreach (var entity in entities)
|
||||
{
|
||||
_context.Entry(entity).State = EntityState.Modified;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Remove(T entity)
|
||||
{
|
||||
_dbSet.Remove(entity);
|
||||
}
|
||||
|
||||
public virtual void RemoveRange(IEnumerable<T> entities)
|
||||
{
|
||||
_dbSet.RemoveRange(entities);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using Microsoft.EntityFrameworkCore.Storage;
|
||||
using MyNewProjectName.Domain.Interfaces;
|
||||
using MyNewProjectName.Infrastructure.Persistence.Context;
|
||||
|
||||
namespace MyNewProjectName.Infrastructure.Persistence.Repositories;
|
||||
|
||||
/// <summary>
|
||||
/// Unit of Work implementation
|
||||
/// </summary>
|
||||
public class UnitOfWork : IUnitOfWork
|
||||
{
|
||||
private readonly ApplicationDbContext _context;
|
||||
private IDbContextTransaction? _transaction;
|
||||
|
||||
public UnitOfWork(ApplicationDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await _context.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public async Task BeginTransactionAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
_transaction = await _context.Database.BeginTransactionAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public async Task CommitTransactionAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
if (_transaction != null)
|
||||
{
|
||||
await _transaction.CommitAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
await RollbackTransactionAsync(cancellationToken);
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (_transaction != null)
|
||||
{
|
||||
await _transaction.DisposeAsync();
|
||||
_transaction = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task RollbackTransactionAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (_transaction != null)
|
||||
{
|
||||
await _transaction.RollbackAsync(cancellationToken);
|
||||
await _transaction.DisposeAsync();
|
||||
_transaction = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_transaction?.Dispose();
|
||||
_context.Dispose();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user