多数据提供者/ ORM上的存储库模式?

时间:2011-07-08 06:00:26

标签: c# entity-framework orm repository design-patterns

我只想说我有以下数据模型:

public class Account
{
   public string Username { get; set; }
   public string Password { get; set; }
}

public class Configuration
{
   public string Key { get; set; }
   public string Value { get; set; }
}

目前,他们每个人都有自己的数据访问存储库,并使用实体框架作为其工作单元/ DbContext。我打算从实体框架中取出配置部分,并使用Redis或Memcached作为其数据访问。我甚至可能将EF切换到NHibernate或根本没有ORM,我可能会将数据库切换到MongoDB或CouchDB。

这样做的好方法是什么?在我的业务逻辑中不知道所有那些较低层的东西?使用什么样的模式?设计这样的变化是否可能或者只是坏事?

谢谢:)

2 个答案:

答案 0 :(得分:4)

正如前一篇文章所述,你应该采用“界面的方式”。 我个人并没有直接为每个orm实现存储库,但我使用了一些变化。 用你的例子......

public interface IAccountRepository
{
  Account Get(int id);
  void Delete(int id);
  ...other method...
}

然后你创建你的存储库

public class AccountRepository : IAccountRepository
{
   private readonly IUnitofWork unitofWork;

   public AccountRepository(IUnitofWork unitofWork)
   {
      this.unitofWork = unitofWork;
   }

   //Implement interface method
   public Account Get(int id)
   {
      //some logic or just the call to the unit of work
      return unitofWork.Get(id);
   }
}

我很满意这个解决方案,因为我最终只有一个存储库,90%的时间使用linq来查询,所以我不必为每个工作单元编写sql,每次我必须写一个带有分页的“GetAllProducts”我不必为每个工作单元编写相同的代码(和测试),但仅限于我的存储库。这显然是一个简单的例子,所以我希望你能得到这个想法。 您可以创建一个RepositoryBase来实现使用linq的方法Find()或Query()。 然后使用您的Castle Windsor或ninject或任何您可以注入的工作单元。希望它有所帮助。

更新: 我的UnitofWorkBase实现nhibernate的样本类似于:

public class NHUnitofWork<T> : IUnitofWork<T> where T : EntityBase
{
protected INHSessionBuilder SessionBuilder { get; private set; }

public NHPersistorBase(INHSessionBuilder sessionBuilder)
{
  SessionBuilder = sessionBuilder;
}

public T Get(int id)
{
  T result = null;
  ISession session = SessionBuilder.GetSession();
  using (ITransaction transaction = session.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
  {
    try
    {
      result = (T)session.Get(typeof(T), id);
      transaction.Commit();
    }
    finally
    {
      if (transaction.IsActive)
        transaction.Rollback();
    }
  }
  return result;
}
public IQueryable<T> Find()
{
  return SessionBuilder.GetSession().Query<T>();
}

}

答案 1 :(得分:1)

使用界面。

public class IAccountRespository
{
   public Account LoadAccountByUsername(String Username);
   public void DeleteAccont(Account a);
   public void SaveAccont(Account a);
   .
   .
   .
   ...more methods
}

然后在每个数据访问对象(ef,mongdb等)上实现此接口。

在您的业务逻辑代码中,您只使用接口而不是实际对象。

我使用工厂模式来创建数据访问对象,但您可以使用每个IoC模式。