Asp.net-Mvc

每種實現的儲存庫模式優缺點

  • March 24, 2021

嗨,看看通常似乎實現如下的儲存庫模式:

public class GenericRepository<TEntity> where TEntity : class
{
   // other business

   public virtual TEntity GetByID(object id)
   {
       return db.Set().Find(id);
   }

   public virtual void Insert(TEntity entity)
   {
       db.Set().Add(entity);
   }

   public virtual void Delete(object id)
   {
       TEntity entityToDelete = db.Set().Find(id);
       Delete(entityToDelete);
   }

   public virtual void Update(TEntity entityToUpdate)
   {
       db.Set().Attach(entityToUpdate);
       context.Entry(entityToUpdate).State = EntityState.Modified;
   }
}

因此,對於您想要使用的每種類型(即更新),您需要實例化一個儲存庫。

因此,如果我有兩種我想保存的類型CarsTrucks我需要去:

var carRepository = new GernericRepository<Car>();
carRepository.Update(myCar);

var truckRepository = new GernericRepository<Truck>();
carRepository.Update(myTruck);

因此,您對每種類型都有單獨的儲存庫。為了確保您一次保存所有內容,您需要unitOfWork確保它們都使用相同的上下文並一次保存。

擁有類似的東西肯定不是更好:

public class GenericRepository
{
   // other business

   public virtual TEntity GetByID<TEntity>(object id) where TEntity : class
   {
       return db.Set<TEntity>().Find(id);
   }

   public virtual void Insert<TEntity>(TEntity entity) where TEntity : class
   {
       db.Set<TEntity>().Add(entity);
   }

   public virtual void Delete<TEntity>(object id) where TEntity : class
   {
       TEntity entityToDelete = db.Set<TEntity>().Find(id);
       Delete(entityToDelete);
   }

   public virtual void Update<TEntity>(TEntity entityToUpdate) where TEntity : class
   {
       db.Set<TEntity>().Attach(entityToUpdate);
       context.Entry(entityToUpdate).State = EntityState.Modified;
   }
}

這意味著儲存庫只需要實例化一次,因此真的是通用的嗎?

所以你可以像這樣更新你的汽車和卡車:

var repository = new GernericRepository<Car>();
repository.Update<Car>(myCar);
rRepository.Update<Truck>(myTruck);

當然這是一個更好的方法?我錯過了什麼嗎?它也自動只有一個上下文。

儲存庫模式不會將數據訪問與數據儲存分離,這正是 NHibernate 或 Enity Framework 等 ETL 工具所做的事情。儲存庫模式為提取數據提供了可重用的方法。

正如您所描述的那樣,我以前使用過一個所謂的“通用”儲存庫,並認為它很棒。直到您意識到您剛剛在 NHibernate 或實體框架之上添加了另一層,您才意識到這一切都消失了 Pete Tong。

理想情況下,您需要的是描述從數據儲存中獲取數據的方式的介面,並且不應該洩露您正在使用的數據訪問權限。例如:

public interface IEmployee 
{
   IEmployee GetEmployeeById(Guid employeeId);

   IEmployee GetEmployeeByEmployeeNumber(string employeeNumber);

   IEnumerable<IEmployee> GetAllEmployeesWithSurname(string surname);

   IEnumerable<IEmployee> GetAllEmployeesWithStartDateBetween(DateTime beginDateTime, DateTime endDateTime);
}

這為您提供了一個程式碼契約,不了解您的持久層,並且用於檢索數據的查詢可以單獨進行單元測試。該介面可以從提供通用 CRUD 方法的基本介面繼承,但您會假設您的所有儲存庫都需要 CRUD。

如果您走通用儲存庫的道路,您最終會在查詢中出現重複,並且您會發現對使用儲存庫的程式碼進行單元測試要困難得多,因為您還必須測試查詢。

引用自:https://stackoverflow.com/questions/6852595