Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Model view controller 存储库模式&x2B;工作单位_Model View Controller_Design Patterns_Repository_Unit Of Work - Fatal编程技术网

Model view controller 存储库模式&x2B;工作单位

Model view controller 存储库模式&x2B;工作单位,model-view-controller,design-patterns,repository,unit-of-work,Model View Controller,Design Patterns,Repository,Unit Of Work,差不多一年之后,我开始了一个新的mvc项目,这次是版本4。我想知道以下存储库模式的实现是否弊大于利 public interface IRepository<T> where T : class { IEnumerable<T> GetAll(); IQueryable<T> Query(Expression<Func<T, bool>> filter); void Add(T entity); v

差不多一年之后,我开始了一个新的mvc项目,这次是版本4。我想知道以下存储库模式的实现是否弊大于利

public interface IRepository<T> where T : class
{
    IEnumerable<T> GetAll();

    IQueryable<T> Query(Expression<Func<T, bool>> filter);

    void Add(T entity);

    void Remove(T entity);
}

public interface IUnitOfWork
{
    void Commit();
}

public interface IDbContext : IDisposable
{
    IDbSet<T> Set<T>() where T : class;

    int SaveChanges();
}

public class DbContextAdapter : IDbContext
{
    private readonly DbContext _myRealContext;

    public DbContextAdapter()
    {
        this._myRealContext = new EstafaContext();
    }

    public void Dispose()
    {
        _myRealContext.Dispose();
    }

    public IDbSet<T> Set<T>() where T : class
    {
        return _myRealContext.Set<T>();
    }

    public int SaveChanges()
    {
        return _myRealContext.SaveChanges();
    }
}

public class SqlRepository<T> : IRepository<T> where T : class
{
    private IDbSet<T> _dbSet;

    public SqlRepository(IDbContext dbContext)
    {
        this._dbSet = dbContext.Set<T>();
    }

    public IEnumerable<T> GetAll()
    {
        return this._dbSet.ToList();
    }

    public IQueryable<T> Query(Expression<Func<T, bool>> filter)
    {
        return this._dbSet.Where(filter);
    }

    public void Add(T entity)
    {
        this._dbSet.Add(entity);
    }

    public void Remove(T entity)
    {
        this._dbSet.Remove(entity);
    }
}

public class SqlUnitOfWork : IDisposable, IUnitOfWork
{
    private IDbContext _dbContext;

    private SqlRepository<Cliente> _clientes ;

    public SqlUnitOfWork()
    {
        this._dbContext = new DbContextAdapter();
    }

    public void Dispose()
    {
        if (this._dbContext != null)
        {
            this._dbContext.Dispose();
        }
        GC.SuppressFinalize(this);
    }

    public IRepository<Cliente> Clientes
    {
        get { return _clientes ?? (_clientes = new SqlRepository<Cliente>(_dbContext)); }
    }       

    public void Commit()
    {
        this._dbContext.SaveChanges();
    }
}
公共接口i假设,其中T:class
{
IEnumerable GetAll();
IQueryable查询(表达式过滤器);
无效添加(T实体);
无效删除(T实体);
}
公共接口工作单元
{
无效提交();
}
公共接口IDbContext:IDisposable
{
IDbSet Set(),其中T:class;
int SaveChanges();
}
公共类DbContextAdapter:IDbContext
{
私有只读DbContext\u myRealContext;
公共DbContextAdapter()
{
这是。_myRealContext=new EstafaContext();
}
公共空间处置()
{
_myRealContext.Dispose();
}
公共IDbSet Set(),其中T:class
{
返回_myRealContext.Set();
}
公共int SaveChanges()
{
返回_myRealContext.SaveChanges();
}
}
公共类SqlRepository:IRepository,其中T:class
{
私有IDbSet _dbSet;
公共SqlRepository(IDbContext dbContext)
{
这是._dbSet=dbContext.Set();
}
公共IEnumerable GetAll()
{
返回此项。_dbSet.ToList();
}
公共IQueryable查询(表达式筛选器)
{
返回此值。\u dbSet.Where(过滤器);
}
公共无效添加(T实体)
{
本._dbSet.Add(实体);
}
公共无效删除(T实体)
{
本._dbSet.Remove(实体);
}
}
公共类SqlUnitOfWork:IDisposable,IUnitOfWork
{
私有IDbContext _dbContext;
私人SqlRepository_客户;
公共SqlUnitOfWork()
{
这是._dbContext=new DbContextAdapter();
}
公共空间处置()
{
if(this.\u dbContext!=null)
{
这是._dbContext.Dispose();
}
总干事(本);
}
公共电子商务客户
{
获取{return\u clientes???(\u clientes=newsqlrepository(\u dbContext));}
}       
公共无效提交()
{
这是._dbContext.SaveChanges();
}
}
这样,我可以通过SqlUnitOfWork从一个点管理所有存储库。 我在以前的一个项目中使用了这个设计,效果很好,但我觉得它效率不高,可能是多余的。 添加这样一个抽象层值得吗


提前谢谢

虽然我的实现与您的实现不完全一样,但对我来说它似乎非常可靠

我通常做的唯一其他更改是为每个实体类型存储库定义特定接口,如下所示:

public interface IClienteRepository : IRepository<Cliente>
{
  IEnumerable<Cliente> GetByName(string firstName);
  // etc
}
公共接口IClienterpository:IRepository
{
IEnumerable GetByName(字符串名);
//等
}
这样,我仍然可以在CRUD操作中通用地使用所有存储库,但我也可以使用相同的存储库来抽象出一些查询逻辑。存储库的用户只需要知道他们想要什么,而不需要知道如何获得它


当然,这有点繁琐,需要您对存储库进行具体的实现,以添加额外的功能,但它只是封装了查询逻辑,您可以通过应用程序在其他地方使用这些逻辑。

我不知道它是否有更多的缺点或优点,但多年来,我发现这种类型的存储库模式越来越没用了。除非在飞行中切换数据库或数据源是一种真正的可能性,或者如果你需要一些疯狂的模拟宇宙测试覆盖率,我认为这比它的价值更麻烦

这只是我个人的喜好,但我喜欢我的数据访问方法更明确一点。例如,如果我将模型返回到视图中,它们肯定会与数据库中的表不同。所以我想要一个
GetAllModelX
方法,而不是
GetAllDbTableRows
方法

那么,转换代码将存放在哪里呢?在控制器中?另一个将实体转换为模型的数据访问层?答案是对的还是错的?可能不会


我在这里肯定是在扮演魔鬼代言人的角色,但根据我的经验,我已经摆脱了这种通用存储库设计,转而选择了一个数据访问层,该层返回/接受模型,并使用EF处理所有针对数据库的查询/CRUDding/UnitOfWork。但话说回来,我是一个典型的单元测试人员,不会做太多的模拟,而且会做更多的集成测试。

虽然我同意将尽可能多的工作推到“层”,但“服务”层不是与存储库/实体交互和构建域级模型的理想场所吗?当然是。但是,如果您的存储库所做的只是避免客户机必须显式地编写代码
SaveChanges()
,那么您真正要做的是什么?写100行代码以避免以后再写20行?我只是发现,您经常会与这样的存储库发生冲突,因为它破坏了“工作单元”名称的灵活性。我还应该指出,我通常处理大型事务,而且我的数据访问操作从来没有像直接对数据库进行添加/更新那样简单。很明显,像这样一个简单的存储库对我这样的人没有什么好处。这种类型的设计肯定是有案例的,但即使是在简单的网站场景中,我发现它通常都是过度的,我在很大程度上同意你的观点。只要我在维护存储库模式,我相信最大的动机就是从应用程序的其余部分抽象出数据访问。通过使用POCOs和通用存储库接口,您可以在任意选择(EF/Ninject/Linq2Sql等)之间交换数据访问,而不会影响应用程序的其他部分。这种情况发生的频率如何,以及“榨汁物有所值”是否值得商榷。我仅以客户线为例。很明显,我会有更多的实体。THX@armen,我看到你了