【问题标题】:Is it possible to create a generic Repository class for all my objects?是否可以为我的所有对象创建一个通用的 Repository 类?
【发布时间】:2019-05-19 00:37:59
【问题描述】:

我有以下 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);
        }
    }

【问题讨论】:

    标签: c# entity-framework entity-framework-4 entity-framework-4.1


    【解决方案1】:

    是的,你可以在这里:

    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);
            }
        }
    }
    

    工作单元:

    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);
            }
        }
    

    【讨论】:

    • 我不需要 dbset.SaveALl() 吗??
    • 你需要它,但在我的项目中,我使用了工作单元来执行此操作,并将其代码也粘贴在上面
    • 如果你愿意,你可以忽略 unitOfWork,只需将 Save 放入存储库本身
    • 我不明白为什么在工作单元中你有一个 UserRepository 引用,如果你有一个通用的 baserepository,你不应该引用 baserepository 吗?
    • 我想调用 UserRepository 特定的函数,而不仅仅是 baserepository 函数。
    【解决方案2】:

    一段时间以来,我一直在我的项目中使用这个通用存储库实现:

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

    它最初是为 EF4 设计的,但在我看来,可以修改实现以使用 EF4.1 代码优先。

    【讨论】:

      【解决方案3】:

      你可以试试:

      1. 要使用此生成器:http://efrepository.codeplex.com/
      2. 自己做类似的。
      3. 使用 Visual Studio 生成简单的方法并将自定义查询添加到从存储库继承的类中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-08-18
        • 1970-01-01
        • 2011-03-11
        • 2019-10-17
        • 1970-01-01
        • 1970-01-01
        • 2016-09-25
        相关资源
        最近更新 更多