Можно ли создать общий класс репозитория для всех моих объектов? - PullRequest
6 голосов
/ 14 октября 2011

У меня есть следующий класс 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);
        }
    }

Ответы [ 3 ]

9 голосов
/ 14 октября 2011

да, вы можете вот один:

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);
        }
    }
1 голос
/ 14 октября 2011

Вы можете попробовать:

  1. Чтобы использовать этот генератор: http://efrepository.codeplex.com/.
  2. Чтобы сделать подобное самостоятельно.
  3. Создать тривиальные методы с помощью Visual Studio и добавитьВаши пользовательские запросы в классе, который наследуется от хранилища.
1 голос
/ 14 октября 2011

Я уже некоторое время использую эту общую реализацию репозитория с моими проектами:

http://elegantcode.com/2009/12/15/entity-framework-ef4-generic-repository-and-unit-of-work-prototype/

Первоначально она была разработана для EF4, но мне кажется, что реализация моглабыть модифицирован для работы с кодом EF4.1 в первую очередь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...