多数据提供者/ORM上的存储库模式
本文关键字:存储 模式 提供者 ORM 多数据 | 更新日期: 2023-09-27 18:01:27
假设我有以下数据模型:
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。
做这件事的好方法是什么?对我的业务逻辑中那些底层的东西一无所知?使用什么样的模式?为这样的变化而设计是可能的还是糟糕的?
谢谢:)
正如上一篇文章所述,你应该走"界面之路"。我个人不直接实现每个表单的存储库,但我使用了一点变化。用你的例子…
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()方法。然后用你的温莎城堡或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>();
}
}
使用一个接口
public class IAccountRespository
{
public Account LoadAccountByUsername(String Username);
public void DeleteAccont(Account a);
public void SaveAccont(Account a);
.
.
.
...more methods
}
然后在每个数据访问对象(ef, mongodb等)上实现这个接口。
在您的业务逻辑代码中,您只使用接口而不是实际的对象。
我使用工厂模式来创建数据访问对象,但是您可以使用任何IoC模式。