2013-07-18 46 views
0

嗨我想創建一個通用資源庫,首先使用實體​​框架代碼,並將所有內容封裝在UnitOfWork中,但一定是錯誤的,因爲當我嘗試添加並使用封裝的SaveChanges時不起作用。 這裏是我的倉庫代碼:保存更改在封裝UnitOFWork類中不起作用

public class Repository<T> : IRepository<T> where T : class 
{ 
    private DbContext Context { get; set; } 
    private DbSet<T> DbSet 
    { 
     get { return Context.Set<T>(); } 
    } 

    public Repository(DbContext context) 
    { 
     Context = context; 
    } 

    public virtual IEnumerable<T> GetAll() 
    { 
     return DbSet; 
    } 

    public virtual T GetById(int id) 
    { 
     return DbSet.Find(id); 
    } 

    public virtual void Add(T entity) 
    { 
     DbEntityEntry dbEntityEntry = Context.Entry(entity); 
     if (dbEntityEntry.State != EntityState.Detached) 
     { 
      dbEntityEntry.State = EntityState.Added; 
     } 
     else 
     { 

      DbSet.Add(entity); 
     } 
    } 

    public virtual void Update(T entity) 
    { 
     DbEntityEntry dbEntityEntry = Context.Entry(entity); 
     if (dbEntityEntry.State == EntityState.Detached) 
     { 
      DbSet.Attach(entity); 
     } 
     DbSet.Attach(entity); 
    } 

    public virtual void Remove(T entity) 
    { 
     DbEntityEntry dbEntityEntry = Context.Entry(entity); 
     if (dbEntityEntry.State != EntityState.Deleted) 
     { 
      dbEntityEntry.State = EntityState.Deleted; 
     } 
     else 
     { 
      DbSet.Attach(entity); 
      DbSet.Remove(entity); 
     } 
    } 

    public virtual void Remove(int id) 
    { 
     var entity = GetById(id); 
     if (entity == null) 
     { 
      return; 
     } 
     Remove(entity); 
    } 
} 

這裏是我的UnitOfWork代碼:

public class UnitOfWork 
{ 
    private readonly RepositoryFactory repositoryFactory; 

    private DatabaseContext DbContext 
    { 
     get { return new DatabaseContext(); } 
    } 

    public IRepository<Product> Products 
    { 
     get 
     { 
      return repositoryFactory.GetRepository<Product>(DbContext); 
     } 
    } 

    public UnitOfWork() 
    { 
     repositoryFactory = new RepositoryFactory(); 
    } 

    public void SavaChanges() 
    { 
     DbContext.SaveChanges(); 
    } 
} 

這是我打電話添加數據和獲取數據的代碼:

var sa = new UnitOfWork(); 
var repository = sa.Products;; 
var result = repository.GetAll(); 
var resultbyId = repository.GetById(3); 

var product = new Product() 
{ 
    Name = "sddasd", 
    CategoryId = 1, 
    SubcategoryId = 1, 
    Price = 21, 
    Description = "dsadasfas", 
    ImagePath = "Dsadas", 
    NumberOfProducts = 29 
    }; 
    repository.Add(product); 
    sa.SavaChanges() 

後運行這段代碼似乎出於某種原因,我在我的UnitOfWork類中封裝的SaveChanges不起作用。

但是,如果如我之後DbSet.Add(實體)加入這一行

Context.SaveChanges() 

看來,對象獲取的添加到數據庫中。

如何使我的UnitOfWork SaveChanges方法正常工作?

+0

如何在存儲庫上實現IDisposable,並重用EF內置的工作單元? –

回答

2

在你的代碼的問題是在這裏:

private DatabaseContext DbContext 
{ 
    get { return new DatabaseContext(); } 
} 

你所切實做好是創建每次你的財產被訪問一個新的上下文。當您的Repository<T>正確保存一個上下文並重新使用同一個上下文時,當您撥打UnitOfWork.SaveChanges時,您將保存新創建的上下文,但不會更改。

本着UnitOfWork的精神,您希望您的上下文能夠在封閉類的整個生命週期中生存(UnitOfWork)。試試這個:

private DatabaseContext dbContext; 
private DatabaseContext DbContext 
{ 
    get { return dbContext ?? (dbContext = new DatabaseContext()); } 
} 

這樣,你的DatabaseContext只會在你UnitOfWork的壽命創建一次,在第一次訪問DbContext財產。

+0

更好的是,上下文應該注入存儲庫。通過這種方式,您可以在同一工作單元的不同存儲庫中重複使用相同的上下文。 –

+0

@WiktorZychla上下文已經在註冊庫中「注入」了。它作爲構造函數參數傳遞。除非我想念他的代碼。 –

+0

的確,我一定錯過了。 –