What is the Repository in C#
The repository is a design pattern to help organize the source code for easy maintenance and extension in the future. The Repository will contain the basic method(CRUD) of the entity
- C: Create
- R: Retrieve
- U: Update
- D: Delete
From that, we can reduce the development time and increase the quality of the product.
There are two kinds of implementation of the Repository Design Pattern:
1. Single Repository
One table on the Database will have 1 Repository.
2. Generic Repository(Recommended)
We build 1 Generic class with the basic method CRUD use for all entity.
Example:
Generic Repository Interface
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
namespace IRepositories
{
public interface IGenericRepository<TEntity> : IDisposable where TEntity : class
{
IEnumerable<TEntity> GetAll(bool isAsNoTracking = false);
TEntity Find(params object[] keyValues);
IEnumerable<TEntity> FindBy(Expression<Func<TEntity, bool>> predicate);
TEntity Add(TEntity entity);
void AddRange(List<TEntity> entities);
TEntity Update(TEntity entity);
TEntity Delete(TEntity entity);
void Delete(object id);
void DeleteRange(List<TEntity> entities);
IQueryable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>,
IOrderedQueryable<TEntity>> orderBy = null,
List<Expression<Func<TEntity, object>>>
includeProperties = null,
int? page = null,
int? pageSize = null, bool isAsNoTracking = false);
bool Exist(
Expression<Func<TEntity, bool>> filter = null);
}
}
Generic Repository Interface Implementation
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using log4net;
using Commons.Exceptions;
using Commons.Helpers;
using Commons.Logs;
using IRepositories;
namespace Repositories
{
public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class
{
private DbContext _context;
private readonly DbSet<TEntity> _dbSet;
private readonly ILog _log;
public GenericRepository(DbContext context, ILogManager<TEntity> logManager)
{
_context = context;
_dbSet = context.Set<TEntity>();
_log = logManager.GetLog();
}
public IEnumerable<TEntity> GetAll(bool isAsNoTracking = false)
{
try
{
if (isAsNoTracking)
{
return _dbSet.AsNoTracking().AsEnumerable();
}
return _dbSet.AsEnumerable();
}
catch (Exception ex)
{
// please implement your logs here
}
}
public TEntity Find(params object[] keyValues)
{
try
{
return _dbSet.Find(keyValues);
}
catch (Exception ex)
{
// please implement your logs here
}
}
public IEnumerable<TEntity> FindBy(Expression<Func<TEntity, bool>> predicate)
{
try
{
return _dbSet.Where(predicate).AsNoTracking().AsEnumerable();
}
catch (Exception ex)
{
// please implement your logs here
}
}
public TEntity Add(TEntity entity)
{
try
{
return _dbSet.Add(entity);
}
catch (Exception ex)
{
// please implement your logs here
}
}
public void AddRange(List<TEntity> entities)
{
try
{
_dbSet.AddRange(entities);
}
catch (Exception ex)
{
// please implement your logs here
}
}
public TEntity Update(TEntity entity)
{
try
{
_context.Entry(entity).State = EntityState.Modified;
return entity;
}
catch (Exception ex)
{
// please implement your logs here
}
}
public TEntity Delete(TEntity entity)
{
try
{
if (_context.Entry(entity).State == EntityState.Detached)
{
_dbSet.Attach(entity);
}
return _dbSet.Remove(entity);
}
catch (Exception ex)
{
// please implement your logs here
}
}
public void Delete(object id)
{
try
{
var entityToDelete = _dbSet.Find(id);
Delete(entityToDelete);
}
catch (Exception ex)
{
// please implement your logs here
}
}
public void DeleteRange(List<TEntity> entities)
{
try
{
_dbSet.RemoveRange(entities);
}
catch (Exception ex)
{
// please implement your logs here
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected void Dispose(bool disposing)
{
if (disposing)
{
if (_context != null)
{
_context.Dispose();
_context = null;
}
}
}
public virtual IQueryable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>,
IOrderedQueryable<TEntity>> orderBy = null,
List<Expression<Func<TEntity, object>>>
includeProperties = null,
int? page = null,
int? pageSize = null, bool isAsNoTracking = false )
{
try
{
IQueryable<TEntity> query = _dbSet;
if (includeProperties != null)
includeProperties.ForEach(i => { query = query.Include(i); });
if (filter != null)
query = query.Where(filter);
if (orderBy != null)
query = orderBy(query);
if (page != null && pageSize != null)
query = query
.Skip((page.Value - 1) * pageSize.Value)
.Take(pageSize.Value);
if (isAsNoTracking)
{
query = query.AsNoTracking();
}
return query;
}
catch (Exception ex)
{
// please implement your logs here
}
}
public virtual bool Exist(
Expression<Func<TEntity, bool>> filter = null)
{
try
{
var result = false;
if (filter != null)
{
result = _dbSet.Where(filter).Any();
if (result == false)
{
result = _dbSet.Local.AsQueryable().Where(filter).Any();
}
}
return result;
}
catch (Exception ex)
{
// please implement your logs here
}
}
}
}
I recommend using the Generic Repository because it's flexible and easy to extend in the future.
I hope it can help,
إرسال تعليق
Thank for leaving message