A set of reusable and optimized code for EF Core.
- Implementations for
UnitOfWorkandRepositorypattern. - Implementations for
Storepattern. - Track and store
DbContextchanges.
Install the package with Nuget.
dotnet add package CoreSharp.EntityFramework
Entity: Represents a domain object or business object.DbContext: Manages database sessions and operations.UnitOfWork(UoW): Manages transactions and database connections (a wrapper aroundDbContext).Repository: Abstracts data access, typically read-only.Store: Manages data state, with read and write access.
- Interfaces
- Abstracts
The Query object is just a convention for
delegate IQueryable<TEntity> Query<TEntity>(IQueryable<TEntity> query);
It is used optionally in Repositories and Stores overloads to adjust the DbSet<TEntity> before querying it.
var highSchoolTeacherIds = (await teacherRepository
.GetAsync(query => query
.Where(teacher => teacher.TeacherType == TeacherType.HighSchool) // Filter
.Select(teacher => new Teacher // Project
{
Id = teacher.Id
})
.AsNoTracking())
.Select(teacher => teacher.Id)
.ToArray();
- Define your entity.
using CoreSharp.EntityFramework.Entities.Abstracts;
public sealed class Teacher : EntityBase<Guid>
{
// Properties
public string Name { get; set; }
}
public sealed class SchoolDbContext : DbContext
{
// Properties
public DbSet<Teacher> Teachers { get; set; }
}
- Define your repository.
using CoreSharp.EntityFramework.Repositories.Interfaces;
public interface ITeacherRepository : IRepository<Teacher, Guid>
{
}
using CoreSharp.EntityFramework.Repositories.Abstracts;
public sealed class TeacherRepository : RepositoryBase<Teacher, Guid>, ITeacherRepository
{
// Constructors
public TeacherRepository(DbContext dbContext)
: base(dbContext)
{
}
}
- Define your UnitOfWork.
using CoreSharp.EntityFramework.Repositories.Interfaces;
public interface ISchoolUnitOfWork : IUnitOfWork
{
// Properties
ITeacherRepository Teachers { get; }
}
using CoreSharp.EntityFramework.Repositories.Abstracts;
public sealed class SchoolUnitOfWork : UnitOfWorkBase, ISchoolUnitOfWork
{
// Fields
private ITeacherRepository _teachers;
// Constructors
public AppUnitOfWork(SchoolDbContext schoolDbContext)
: base(schoolDbContext)
{
}
// Properties
public ITeacherRepository Teachers
=> _teachers ??= new TeacherRepository(Context);
}
- Register UnitOfWork.
public static IServiceProvider AddDatabase(this IServiceCollection serviceCollection)
{
serviceCollection.AddScoped<ISchoolUnitOfWork, SchoolUnitOfWork>();
return serviceCollection;
}
- Inject and use UnitOfWork.
public sealed class SchoolManager
{
private readonly ISchoolUnitOfWork _unitOfWork;
public SchoolManager(ISchoolUnitOfWork unitOfWork)
=> _unitOfWork = unitOfWork;
public Task<IEnumerable<Teacher>> GetTeachersAsync()
=> _unitOfWork.Teachers.GetAsync();
public async Task AddTeachersAsync(Teacher teacherToAdd)
{
await _unitOfWork.Teachers.AddAsync(teacherToAdd);
await _unitOfWork.CommitAsync();
}
}
- Define your entity.
using CoreSharp.EntityFramework.Entities.Abstracts;
public sealed class Teacher : EntityBase<Guid>
{
// Properties
public string Name { get; set; }
}
public sealed class SchoolDbContext : DbContext
{
// Properties
public DbSet<Teacher> Teachers { get; set; }
}
- Define your store.
using CoreSharp.EntityFramework.Stores.Interfaces;
public interface ITeacherStore : IStore<Teacher, Guid>
{
}
using CoreSharp.EntityFramework.Stores.Abstracts;
public sealed class TeacherStore : StoreBase<Teacher, Guid>, ITeacherStore
{
// Constructors
public TeacherStore(DbContext dbContext)
: base(dbContext)
{
}
}
- Register store.
public static IServiceProvider AddDatabase(this IServiceCollection serviceCollection)
{
serviceCollection.AddScoped<ISteacherStore, TeacherStore>();
return serviceCollection;
}
- Inject and use store.
public sealed class SchoolManager
{
private readonly ITeacherStore _teacherStore;
public SchoolManager(ITeacherStore teacherStore)
=> _teacherStore = teacherStore;
public Task<IEnumerable<Teacher>> GetTeachersAsync()
=> _teacherStore.Teachers.GetAsync();
public Task AddTeachersAsync(Teacher teacherToAdd)
=> _teacherStore.Teachers.AddAsync(teacherToAdd);
}