5

我正在尝试实现通用存储库模式。我发现了这个网站,我认为它解释得很好。 http://www.tugberkugurlu.com/archive/generic-repository-pattern-entity-framework-asp-net-mvc-and-unit-testing-triangle

我的目的是为开发人员节省一些时间和按键,我知道这会对我有所帮助。

所以我有两个问题:
1.这是否是一个好方法,我将来会遇到一些问题吗?
2. 怎么和Unitofwork模式结合呢?当然不能创建抽象类的实例,所以下面的代码无效。

public class UnitOfWork : IDisposable
    {
        #region Private fields
        private readonly MyCompanyContext _context = new MyCompanyContext();
        private GenericRepository<MyCompanyContext, Task> _taskRepository;

        public GenericRepository<MyCompanyContext, Task> TaskRepository
        {
            get
            {
                return _taskRepository ??
                         (_taskRepository = new GenericRepository<MyCompanyContext, Task>());
            }
        }




namespace MyCompany.DAL.Repository
{
    public interface IGenericRepository<T> where T : class
    {
        IQueryable<T> GetAll();
        IQueryable<T> FindBy(Expression<Func<T, bool>> predicate);
        void Add(T entity);
        void Delete(T entity);
        void Edit(T entity);
        void Save();
    }

    public abstract class GenericRepository<C, T> :
    IGenericRepository<T>
        where T : class
        where C : DbContext, new()
    {

        private C _entities = new C();
        public C Context
        {

            get { return _entities; }
            set { _entities = value; }
        }

        public virtual IQueryable<T> GetAll()
        {

            IQueryable<T> query = _entities.Set<T>();
            return query;
        }

        public IQueryable<T> FindBy(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
        {
            IQueryable<T> query = _entities.Set<T>().Where(predicate);
            return query;
        }

        public virtual void Add(T entity)
        {
            _entities.Set<T>().Add(entity);
        }

        public virtual void Delete(T entity)
        {
            _entities.Set<T>().Remove(entity);
        }

        public virtual void Edit(T entity)
        {
            _entities.Entry(entity).State = System.Data.EntityState.Modified;
        }

        public virtual void Save()
        {
            _entities.SaveChanges();
        }
    }
}
4

2 回答 2

5

关于存储库有几种意见,但是在我自己在生产中尝试了各种存储库实现几年之后,我同意Ayende 的观点,即存储库,尤其是通用的,是冗余的抽象层。

我非常喜欢这门课程: http ://www.pluralsight-training.net/microsoft/Courses/TableOfContents/linq-architecture

它遍历了大多数可能的解决方案并解释了好坏。

我们现在使用的是对数据上下文的非常薄的抽象,只是为了克服 Linq2Sql 的可测试性问题,这在大多数情况下在使用 EF 时是无关紧要的。

于 2012-07-03T08:45:55.190 回答
2

付出很多努力,你可能会得到它的工作,但我想知道这种努力是否真的值得?我以前见过这样的实现,在尝试管理多对多关系时它们真的很困难(想想在你的场景中你将如何管理它)。您正在使用实体框架,一个 ORM 对吗?设计了 Entity Framework 和 nHibernate 等 ORM从应用程序代码中抽象出数据库实现,那么在它之上添加另一个抽象来管理如此细粒度的实体的目的是什么?如果是测试问题,那么您可以使用模拟框架来模拟上下文,从而在测试期间无需实际数据库。但是,如果出于架构或安全原因,您正在寻求从应用程序代码中删除与数据库上下文的交互,我建议您在实体框架顶部使用命令模式的实现来实现实用主义。我需要在更大规模的企业(银行)应用程序上执行此操作,出于安全原因(正确或错误),我们绝对不允许在我们的应用程序代码中建立数据库连接。

于 2012-07-03T08:46:37.093 回答