Skip to content

efthymios-ks/CoreSharp.EntityFramework

Repository files navigation

CoreSharp.EntityFramework

Nuget Coverage Quality Gate Status GitHub License

A set of reusable and optimized code for EF Core.

Features

  • Implementations for UnitOfWork and Repository pattern.
  • Implementations for Store pattern.
  • Track and store DbContext changes.

Installation

Install the package with Nuget.

dotnet add package CoreSharp.EntityFramework

Terminology

  • Entity: Represents a domain object or business object.
  • DbContext: Manages database sessions and operations.
  • UnitOfWork (UoW): Manages transactions and database connections (a wrapper around DbContext).
  • Repository: Abstracts data access, typically read-only.
  • Store: Manages data state, with read and write access.

Documentation

Important files

Query object

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();

Use cases

Table of Contents

Repository pattern

  1. 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; } 
}
  1. 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)
    {
    }
}
  1. 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);
}
  1. Register UnitOfWork.
public static IServiceProvider AddDatabase(this IServiceCollection serviceCollection)
{
    serviceCollection.AddScoped<ISchoolUnitOfWork, SchoolUnitOfWork>();

    return serviceCollection;
}
  1. 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();
    }
}

Store pattern

  1. 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; } 
}
  1. 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)
    {
    }
}
  1. Register store.
public static IServiceProvider AddDatabase(this IServiceCollection serviceCollection)
{
    serviceCollection.AddScoped<ISteacherStore, TeacherStore>();

    return serviceCollection;
}
  1. 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); 
}

About

No description, website, or topics provided.

Resources

License

Stars

1 star

Watchers

1 watching

Forks

Contributors

Languages