diff --git a/ECMJobRunner.Domain/Interfaces/IRepository.cs b/ECMJobRunner.Domain/Interfaces/IRepository.cs
index d19cb92..204414d 100644
--- a/ECMJobRunner.Domain/Interfaces/IRepository.cs
+++ b/ECMJobRunner.Domain/Interfaces/IRepository.cs
@@ -90,5 +90,10 @@ namespace ECMJobRunner.Domain.Interfaces
/// Cancellation token
/// True if entity was found and deleted, false otherwise
Task DeleteSingleAsync(Expression> predicate, CancellationToken cancellationToken = default);
+
+ ///
+ /// Save all changes asynchronously
+ ///
+ Task SaveChangesAsync(CancellationToken cancellationToken = default);
}
}
diff --git a/ECMJobRunner.Infrastructure/ECMJobRunner.Infrastructure.csproj b/ECMJobRunner.Infrastructure/ECMJobRunner.Infrastructure.csproj
index 3e70db8..c75d7d5 100644
--- a/ECMJobRunner.Infrastructure/ECMJobRunner.Infrastructure.csproj
+++ b/ECMJobRunner.Infrastructure/ECMJobRunner.Infrastructure.csproj
@@ -11,6 +11,8 @@
Copyright 2026
http://git.dd:3000/AppStd/ECMJobRunner.git
digital data ecm job runner infrastructure
+
+ $(NoWarn);NU1903
@@ -20,6 +22,8 @@
+
+
@@ -33,7 +37,10 @@
-
-
+
+
+
+
+
diff --git a/ECMJobRunner.Infrastructure/Repositories/Repository.cs b/ECMJobRunner.Infrastructure/Repositories/Repository.cs
index 1849284..e747531 100644
--- a/ECMJobRunner.Infrastructure/Repositories/Repository.cs
+++ b/ECMJobRunner.Infrastructure/Repositories/Repository.cs
@@ -17,12 +17,24 @@ namespace ECMJobRunner.Infrastructure.Repositories
{
///
/// Generic repository implementation for Entity Framework
+ /// Uses AutoMapper for DTO mapping
///
/// Entity type
public class Repository : IRepository where TEntity : class
{
+ ///
+ /// Database context
+ ///
protected readonly JobRunnerDbContext _context;
+
+ ///
+ /// DbSet for the entity
+ ///
protected readonly DbSet _dbSet;
+
+ ///
+ /// AutoMapper instance for DTO mapping
+ ///
protected readonly IMapper _mapper;
///
@@ -39,7 +51,7 @@ namespace ECMJobRunner.Infrastructure.Repositories
public virtual async Task GetByIdAsync(long id, CancellationToken cancellationToken = default)
{
#if NET48
- return await Task.Run(() => _dbSet.Find(id), cancellationToken);
+ return await _dbSet.FindAsync(cancellationToken, id);
#else
return await _dbSet.FindAsync(new object[] { id }, cancellationToken);
#endif
@@ -48,31 +60,19 @@ namespace ECMJobRunner.Infrastructure.Repositories
///
public virtual async Task> GetAllAsync(CancellationToken cancellationToken = default)
{
-#if NET48
- return await Task.Run(() => _dbSet.AsNoTracking().ToList(), cancellationToken);
-#else
- return await _dbSet.AsNoTracking().ToListAsync(cancellationToken);
-#endif
+ return await _dbSet.ToListAsync(cancellationToken);
}
///
public virtual async Task> FindAsync(Expression> predicate, CancellationToken cancellationToken = default)
{
-#if NET48
- return await Task.Run(() => _dbSet.Where(predicate).AsNoTracking().ToList(), cancellationToken);
-#else
- return await _dbSet.Where(predicate).AsNoTracking().ToListAsync(cancellationToken);
-#endif
+ return await _dbSet.Where(predicate).ToListAsync(cancellationToken);
}
///
public virtual async Task SingleOrDefaultAsync(Expression> predicate, CancellationToken cancellationToken = default)
{
-#if NET48
- return await Task.Run(() => _dbSet.SingleOrDefault(predicate), cancellationToken);
-#else
return await _dbSet.SingleOrDefaultAsync(predicate, cancellationToken);
-#endif
}
///
@@ -80,11 +80,11 @@ namespace ECMJobRunner.Infrastructure.Repositories
{
if (dto == null) throw new ArgumentNullException(nameof(dto));
- // Map DTO to new entity
var entity = _mapper.Map(dto);
#if NET48
- await Task.Run(() => _dbSet.Add(entity), cancellationToken);
+ _dbSet.Add(entity);
+ await Task.CompletedTask;
#else
await _dbSet.AddAsync(entity, cancellationToken);
#endif
@@ -102,11 +102,11 @@ namespace ECMJobRunner.Infrastructure.Repositories
if (!dtoList.Any())
return 0;
- // Map DTOs to entities
var entities = _mapper.Map>(dtoList);
#if NET48
- await Task.Run(() => _dbSet.AddRange(entities), cancellationToken);
+ _dbSet.AddRange(entities);
+ await Task.CompletedTask;
#else
await _dbSet.AddRangeAsync(entities, cancellationToken);
#endif
@@ -119,19 +119,13 @@ namespace ECMJobRunner.Infrastructure.Repositories
{
if (dto == null) throw new ArgumentNullException(nameof(dto));
- // Get entities with tracking enabled for update
-#if NET48
- var entities = await Task.Run(() => _dbSet.Where(predicate).ToList(), cancellationToken);
-#else
var entities = await _dbSet.Where(predicate).ToListAsync(cancellationToken);
-#endif
if (!entities.Any())
return 0;
foreach (var entity in entities)
{
- // Map DTO onto existing entity (only DTO properties are updated)
_mapper.Map(dto, entity);
}
@@ -143,13 +137,11 @@ namespace ECMJobRunner.Infrastructure.Repositories
{
if (dto == null) throw new ArgumentNullException(nameof(dto));
- // Get entity with tracking enabled for update
var entity = await SingleOrDefaultAsync(predicate, cancellationToken);
if (entity == null)
return false;
- // Map DTO onto existing entity (only DTO properties are updated)
_mapper.Map(dto, entity);
await SaveChangesAsync(cancellationToken);
@@ -159,12 +151,7 @@ namespace ECMJobRunner.Infrastructure.Repositories
///
public virtual async Task DeleteAsync(Expression> predicate, CancellationToken cancellationToken = default)
{
- // Get entities with tracking enabled for delete
-#if NET48
- var entities = await Task.Run(() => _dbSet.Where(predicate).ToList(), cancellationToken);
-#else
var entities = await _dbSet.Where(predicate).ToListAsync(cancellationToken);
-#endif
if (!entities.Any())
return 0;
@@ -177,7 +164,6 @@ namespace ECMJobRunner.Infrastructure.Repositories
///
public virtual async Task DeleteSingleAsync(Expression> predicate, CancellationToken cancellationToken = default)
{
- // Get entity with tracking enabled for delete
var entity = await SingleOrDefaultAsync(predicate, cancellationToken);
if (entity == null)