使用实体框架的存储库模式

Posted

技术标签:

【中文标题】使用实体框架的存储库模式【英文标题】:Repository pattern by using entity framework 【发布时间】:2013-10-23 12:53:39 【问题描述】:

以下是我的代码。我想知道它是真是假。

public interface IRepository<T> : IDisposable

    IQueryable<T> GetAll();
    T Update(T entity);
    T Insert(T entity);
    T GetById(T entity);
    void Delete(T entity);
    void Save();


public class Repository<T> : IRepository<T> where T : class

    private readonly SchoolDBEntities _context;

    public Repository(SchoolDBEntities context)
    
        _context = context;
    

    public IQueryable<T> GetAll()
    
        return _context.Set<T>();
    

    public T Update(T entity)
    
        var result = _context.Set<T>().Attach(entity);
        _context.Entry(entity).State = EntityState.Modified;
        return result;
    

    public T Insert(T entity)
    
        return _context.Set<T>().Add(entity);
    

    public T GetById(T entity)
    
        return _context.Set<T>().Find(entity);
    

    public void Delete(T entity)
    
        _context.Set<T>().Remove(entity);
    

    public void Save()
    
        _context.SaveChanges();
    

    public void Dispose()
    
        _context.Dispose();
    

问题是,我不知道何时何地调用SaveDispose 方法。

【问题讨论】:

【参考方案1】:

不要在IRepository&lt;T&gt;中处理

试试这样的 UnitOfWork 模式

public interface IUnitOfWork : IDisposable

    IRepository<Cart> CartRepository  get; 
    IRepository<Product> ProductRepository  get; 
    void Save();


public class UnitOfWork : IUnitOfWork

    readonly SqlDbContext _context;
    public UnitOfWork()
    
        _context = new SqlDbContext();
    

    private bool _disposed;
    protected virtual void Dispose(bool disposing)
    
        if (!_disposed)
        
            if (disposing)
            
                _context.Dispose();
            
        
        _disposed = true;
    
    public void Dispose()
    
        Dispose(true);
        GC.SuppressFinalize(this);
    

    public void Save()
    
        _context.SaveChanges();
    

    public IGenericRepository<Cart> CartRepository
    
        get  return new Repository<Cart>(_context); 
    

    public IGenericRepository<User> UserRepository
    
        get  return new Repository<User>(_context); 
    

你可以这样称呼它

using (_unitOfWork) 
 
   var p = _unitOfWork.ProductRepository.SingleOrDefault(p => p.Id == productId); 
   _cartRepository.Add(p);
   _unitOfWork.Save(); 

【讨论】:

通常,您会遇到需要从 2 个或更多存储库中调用方法的情况。所以,你将不得不做using (_cartRepository)using (_productRepository),这里基本上你打开和关闭到数据库的连接两次,这可以避免使用像这样的 UnitOfWork 模式using (_unitOfWork) var p = _unitOfWork.ProductRepository.SingleOrDefault(p =&gt; p.Id == productId); _cartRepository.Add(p); _unitOfWork.Save(); 您的评论应该是答案的一部分,以便为您的答案添加推理。【参考方案2】:

我认为这取决于你使用这个 repo 的方式。 所以当你想保存时保存,当你想完成工作时处理......在应用程序关闭等时......

【讨论】:

【参考方案3】:

当您在这里使用Unit of Work 模式时,显然如果(存储库的)用户发送保存更改命令,您应该调用 Save 方法。它可能是一个人在您的编辑表单之一或您的应用程序的其他部分上单击应用更改按钮,它处理一些事务逻辑并基于它保存/丢弃更改。所以基本上,当逻辑更改集准备好保存时,存储库会处理它。

【讨论】:

以上是关于使用实体框架的存储库模式的主要内容,如果未能解决你的问题,请参考以下文章

具有存储库模式的实体框架 DAL、BLL

使用带有实体框架 6 的存储库模式更新记录

为啥存储库模式在实体框架中被广泛使用,好像它很复杂?

使用实体框架、代码优先和 CRUD 操作的存储库模式

实体框架核心存储库模式 - 重复检查

无法使用实体框架更新记录并使用存储库模式进行 ninject