我只想说我有以下数据模型:
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。
这样做的好方法是什么?在我的业务逻辑中不知道所有那些较低层的东西?使用什么样的模式?设计这样的变化是否可能或者只是坏事?
谢谢:)
答案 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模式。