UnitOfWork模式的通用存储库模式

时间:2012-07-03 08:08:36

标签: c# entity-framework entity-framework-4 repository-pattern unit-of-work

我正在尝试实现通用存储库模式。我发现这个网站我觉得很好解释。 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();
        }
    }
}

2 个答案:

答案 0 :(得分:5)

关于存储库有几种意见,但在我自己尝试生产各种存储库几年之后,我同意Ayende's意见,该存储库,尤其是通用存储库,是冗余抽象层。

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

它走过了大多数可能的解决方案并解释了货物和坏处。

我们现在使用的是对datacontext的非常精简的抽象,只是为了克服Linq2Sql可测试性问题,这在大多数情况下与使用EF无关。

答案 1 :(得分:2)

经过很多努力,你可能会有所作为,但我想知道这项努力是否值得呢?我以前见过这样的实现,在尝试管理多对多关系时,他们真的很挣扎(考虑一下如何在你的场景中管理它)。 您正在使用Entity Framework,ORM对吗?像Entity Framework和nHibernate这样的ORM是设计的来从应用程序代码中抽象数据库实现,那么在它上面添加另一个抽象来管理这些粒度级别的实体的目的是什么呢?如果这是一个测试问题,那么您可以使用模拟框架来模拟上下文,从而在测试期间不再需要实际的数据库。但是,出于体系结构或安全性原因,您正试图从应用程序代码中删除与db上下文的交互,我建议在实体框架的顶部使用命令模式的实现实用主义。我需要在更大规模的企业(银行)应用程序上执行此操作,出于安全原因(正确或错误),我们绝对不允许在应用程序代码中使用数据库连接。