添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

Recently I start working on open source project using ASP.Net Core 2.0 & ReactJS
you guy can take a look at Awesome CMS-Core

So every web application need database to working with (obviously). So to follow DRY principles we need some generic way to manipulate with our database (keep create same class with same behaviour just different entity).

In this post I will show you guys how to implement simple Generic Repository Pattern that could reuse for every web application.

Full source code can be found here

First I need to add interface

public interface IGenericRepository<T> where T : class IQueryable<T> Query(); ICollection<T> GetAll(); Task<ICollection<T>> GetAllAsync(); T GetById(int id); Task<T> GetByIdAsync(int id); T GetByUniqueId(string id); Task<T> GetByUniqueIdAsync(string id); T Find(Expression<Func<T, bool>> match); Task<T> FindAsync(Expression<Func<T, bool>> match); ICollection<T> FindAll(Expression<Func<T, bool>> match); Task<ICollection<T>> FindAllAsync(Expression<Func<T, bool>> match); T Add(T entity); Task<T> AddAsync(T entity); T Update(T updated); Task<T> UpdateAsync(T updated); void Delete(T t); Task<int> DeleteAsync(T t); int Count(); Task<int> CountAsync(); IEnumerable<T> Filter( Expression<Func<T, bool>> filter = null, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, string includeProperties = "", int? page = null, int? pageSize = null); IQueryable<T> FindBy(Expression<Func<T, bool>> predicate); bool Exist(Expression<Func<T, bool>> predicate);

Something we need to pay attention is the T keyword on the of interface. That is where our Entity being pass in.

And next is our implementation of GenericRepository

public class GenericRepository<T> : IGenericRepository<T> where T : class private readonly ApplicationDbContext _context; private readonly IUnitOfWork _unitOfWork; public GenericRepository(ApplicationDbContext context) _context = context; _unitOfWork = new UnitOfWork(context); public IQueryable<T> Query() return _context.Set<T>().AsQueryable(); public ICollection<T> GetAll() return _context.Set<T>().ToList(); public async Task<ICollection<T>> GetAllAsync() return await _context.Set<T>().ToListAsync(); public T GetById(int id) return _context.Set<T>().Find(id); public async Task<T> GetByIdAsync(int id) return await _context.Set<T>().FindAsync(id); public T GetByUniqueId(string id) return _context.Set<T>().Find(id); public async Task<T> GetByUniqueIdAsync(string id) return await _context.Set<T>().FindAsync(id); public T Find(Expression<Func<T, bool>> match) return _context.Set<T>().SingleOrDefault(match); public async Task<T> FindAsync(Expression<Func<T, bool>> match) return await _context.Set<T>().SingleOrDefaultAsync(match); public ICollection<T> FindAll(Expression<Func<T, bool>> match) return _context.Set<T>().Where(match).ToList(); public async Task<ICollection<T>> FindAllAsync(Expression<Func<T, bool>> match) return await _context.Set<T>().Where(match).ToListAsync(); public T Add(T entity) _context.Set<T>().Add(entity); _context.SaveChanges(); return entity; public async Task<T> AddAsync(T entity) _context.Set<T>().Add(entity); await _unitOfWork.Commit(); return entity; public T Update(T updated) if (updated == null) return null; _context.Set<T>().Attach(updated); _context.Entry(updated).State = EntityState.Modified; _context.SaveChanges(); return updated; public async Task<T> UpdateAsync(T updated) if (updated == null) return null; _context.Set<T>().Attach(updated); _context.Entry(updated).State = EntityState.Modified; await _unitOfWork.Commit(); return updated; public void Delete(T t) _context.Set<T>().Remove(t); _context.SaveChanges(); public async Task<int> DeleteAsync(T t) _context.Set<T>().Remove(t); return await _unitOfWork.Commit(); public int Count() return _context.Set<T>().Count(); public async Task<int> CountAsync() return await _context.Set<T>().CountAsync(); public IEnumerable<T> Filter(Expression<Func<T, bool>> filter = null, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, string includeProperties = "", int? page = null, int? pageSize = null) IQueryable<T> query = _context.Set<T>(); if (filter != null) query = query.Where(filter); if (orderBy != null) query = orderBy(query); if (includeProperties != null) foreach ( var includeProperty in includeProperties.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) query = query.Include(includeProperty); if (page != null && pageSize != null) query = query.Skip((page.Value - 1) * pageSize.Value).Take(pageSize.Value); return query.ToList(); public IQueryable<T> FindBy(Expression<Func<T, bool>> predicate) return _context.Set<T>().Where(predicate); public bool Exist(Expression<Func<T, bool>> predicate) var exist = _context.Set<T>().Where(predicate); return exist.Any() ? true : false;

I give 2 options for you guys to choose. Is async query and non async query. But my suggest is go for async query.

Next is the UnitOfWork you guys can take a look at here

Last thing, in order to use generic repository in our service class or what ever you want to call. We have to register in our Startup.cs class

services.AddScoped(typeof(IGenericRepository<>), typeof(GenericRepository<>)); services.AddTransient<IUnitOfWork, UnitOfWork>();

To use in our controller class or service class. We only need to use DI pattern like this

private readonly IGenericRepository〈User〉 _userRepository; public AccountController( IGenericRepository〈User〉 userRepository _userRepository = userRepository; public async Task GetAllUser() { var data = await _userRepository.GetAllAsync(); // reset of code

That is. In my next post I will introduce UnitOfWork pattern and how to implement it to clean up our GenericRepository code. Happy coding !!!!

Please provide a sample code as unitofwork and Iunitofwork class/interface missing in above example

Like

I’m already add in here https://ngohungphuc.wordpress.com/2018/05/02/unit-of-work-pattern-in-asp-net-core/

Like

Is the issue with this approach not that the repository is loosely typed? I think for simple implementations of a class this is fine, but if you want a strongly typed class is this not an issue?

Like

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Email Address: Privacy & Cookies: This site uses cookies. By continuing to use this website, you agree to their use.
To find out more, including how to control cookies, see here: Cookie Policy