https://s3-us-west-2.amazonaws.com/secure.notion-static.com/8b2d278a-d686-4840-b78e-736e4d5a33d7/Untitled.png

public interface IStudentRepository : IDisposable
{
	IEnumerable<Student> GetStudents();
	Student GetStudentByID(int studentId);
	void InsertStudent(Student student);
	void DeleteStudent(int studentID);
	void UpdateStudent(Student student);
	void Save();
}

Generic Repository & Unit of Work

public class GenericRepository<TEntity> 
	where TEntity : class
{
	internal SchoolContext context;
	internal DbSet<TEntity> dbSet;

	public GenericRepository(SchoolContext context)
	{
		this.context = context;
		this.dbSet = context.Set<TEntity>();
	}

	public virtual IEnumerable<TEntity> Get(
		Expression<Func<TEntity, bool>> filter = null,
		Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
		string includeProperties = "")
	{
		IQueryable<TEntity> query = dbSet;

		if (filter != null)
			query = query.Where(filter);

		foreach (var includeProperty in includeProperties.Split
			(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
			query = query.Include(includeProperty);

		if (orderBy != null)
			return orderBy(query).ToList();
		else return query.ToList();
	}

	public virtual TEntity GetByID(object id) => return dbSet.Find(id);

	public virtual void Insert(TEntity entity) => dbSet.Add(entity);

	public virtual void Delete(object id)
	{
		TEntity entityToDelete = dbSet.Find(id);
		Delete(entityToDelete);
	}

	public virtual void Delete(TEntity entityToDelete)
	{
		if (context.Entry(entityToDelete).State == EntityState.Detached)
			dbSet.Attach(entityToDelete);
		dbSet.Remove(entityToDelete);
	}

	public virtual void Update(TEntity entityToUpdate)
	{
		dbSet.Attach(entityToUpdate);
		context.Entry(entityToUpdate).State = EntityState.Modified;
	}
}
public class UnitOfWork : IDisposable
{
    private DbContext _Context;

    private GenericRepository<Department> _DepartmentRepository;
    public GenericRepository<Department> DepartmentRepository => 
			_DepartmentRepository ?? new GenericRepository<Department>(_Context);

    private GenericRepository<Course> _CourseRepository;
    public GenericRepository<Course> CourseRepository => 
			_CourseRepository ?? new GenericRepository<Course>(_Context);

    public UnitOfWork(DbContext context) => _Context = context;

    public void Save() => _Context.SaveChanges();

    private bool _Disposed = false;
    protected virtual void Dispose(bool disposing)
    {
        if (!_Disposed && disposing)
            _Context.Dispose();
        _Disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

Implement Query Objects

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/3698681c-6272-4e68-864c-7d4e758833fc/Untitled.png

public IEnumerable<Order> FindActiveOrders() => base.FindAll()
	.Where(order => order.State != OrderState.Closed && order.State != OrderState.Canceled)
	.ToList();
public IEnumerable<Order> FindActiveOrders() => 
	base.FindBySpec(new ActiveOrders()).ToList();