I have the following POCO Class with its Repository Pattern Implementation. If my model is big enough it would make sense to make this generic so only one implementation needs to be done.
Is this possible? Can you please show me how?
public class Position
{
[DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.Identity)]
public int PositionID { get; set; }
[StringLength(20, MinimumLength=3)]
public string name { get; set; }
public int yearsExperienceRequired { get; set; }
public virtual ICollection<ApplicantPosition> applicantPosition { get; set; }
}
public interface IPositionRepository
{
void CreateNewPosition(Position contactToCreate);
void DeletePosition(int id);
Position GetPositionByID(int id);
IEnumerable<Position> GetAllPositions();
int SaveChanges();
IEnumerable<Position> GetPositionByCustomExpression(Expression<Func<Position, bool>> predicate);
}
public class PositionRepository : IPositionRepository
{
private HRContext _db = new HRContext();
public PositionRepository(HRContext context)
{
if (context == null)
throw new ArgumentNullException("context");
_db = context;
}
public Position GetPositionByID(int id)
{
return _db.Positions.FirstOrDefault(d => d.PositionID == id);
}
public IEnumerable<Position> GetAllPosition()
{
return _db.Positions.ToList();
}
public void CreateNewPosition(Position positionToCreate)
{
_db.Positions.Add(positionToCreate);
_db.SaveChanges();
}
public int SaveChanges()
{
return _db.SaveChanges();
}
public void DeletePosition(int id)
{
var posToDel = GetPositionByID(id);
_db.Positions.Remove(posToDel);
_db.SaveChanges();
}
/// <summary>
/// Lets suppose we have a field called name, another years of experience, and another department.
/// How can I create a generic way in ONE simple method to allow the caller of this method to pass
/// 1, 2 or 3 parameters.
/// </summary>
/// <returns></returns>
public IEnumerable<Position> GetPositionByCustomExpression(Expression<Func<Position, bool>> predicate)
{
return _db.Positions.Where(predicate);
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
_db.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
yes, you can here is one:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using System.Data;
namespace Nodes.Data.Repository
{
public class BaseRepository<TEntity>:IRepository<TEntity> where TEntity : class
{
internal SampleDBContext context;
internal DbSet<TEntity> dbSet;
public BaseRepository(SampleDBContext context)
{
this.context = context;
this.dbSet = context.Set<TEntity>();
}
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 DeleteAll(List<TEntity> entities)
{
foreach (var entity in entities)
{
this.Delete(entity);
}
}
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 IQueryable<TEntity> Find(System.Linq.Expressions.Expression<Func<TEntity, bool>> predicate)
{
return dbSet.Where(predicate);
}
}
}
UnitOfWork:
public class UnitOfWork
{
private SampleDBContext context = new SampleDBContext();
private IUserRepository userRepository;
#region PublicProperties
public IUserRepository UserRepository
{
get
{
if (this.userRepository == null)
{
UserRepository repo = new UserRepository(context);
}
return userRepository;
}
}
#endregion
public void Save()
{
context.SaveChanges();
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
context.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
I've been using this generic repository implementation with my projects for some time:
http://elegantcode.com/2009/12/15/entity-framework-ef4-generic-repository-and-unit-of-work-prototype/
It was originally designed for EF4, but it looks to me like the implementation could be modified to work with EF4.1 code-first.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With