是否可以为我的所有对象创建一个通用的Repository类?

Lui*_*cia 6 c# entity-framework entity-framework-4 entity-framework-4.1

我有以下POCO类及其存储库模式实现.如果我的模型足够大,那么制作这个通用是有意义的,因此只需要完成一个实现.

这可能吗?你能告诉我怎么样吗?

 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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

Amr*_*rhy 9

是的,你可以在这里:

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

的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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

链接下载我写的模板项目.
http://amrelgarhy.com/wp-content/uploads/2011/10/TreeNodesWebsiteTemplate_V1.zip