我目前正在开发一个小型的ASP.NET MVC项目 我试图实现Nhibernate持久化MS Sql Server数据库。 花了很长时间研究DDD和互联网上发现的其他项目后,我决定采用存储库模式。 现在我面临两难选择 使用Nhinbernate时我真的需要一个存储库吗? 拥有一个与Nhinbernate交互的服务层(我目前没有服务层)不是更好,避免写多次这样的事情:
public Domain.Reminder GetById(Guid Code)
{
return (_session.Get<Domain.Reminder>(Code));
}
public Domain.Reminder LoadById(Guid Code)
{
return (_session.Load<Domain.Reminder>(Code));
}
public bool Save(Domain.Reminder Reminder)
{
_session.SaveOrUpdate(Reminder);
return (true);
}
public bool Delete(Domain.Reminder Reminder)
{
_session.Delete(Reminder);
return (true);
}
我找到了一个旧的Ayende的POST,这是针对存储库的 我知道围绕这些主题有一个很大的争论,答案总是......依赖,但在我看来,由于抽象层次过多,事情变得更加复杂,难以理解。 我错了吗?
答案 0 :(得分:7)
Ayende反对以你的方式编写存储库,因为你提出这个问题的原因,它是重复的代码,NH无论如何都可以处理所有这些问题。他提倡像你一样直接打电话给NH,并且不再担心它。
我非常赞同他。除了更多的工作之外,真的没什么可收获的。
答案 1 :(得分:4)
请改用通用存储库。每个类的一个存储库很容易过度。
我使用一个存储库,包含Get,Load,Save方法和各种匹配方法(一个用于Linq,另一个用于我的域查询)。
public class NHibernateRepository : IRepository
{
private readonly ISession _session;
public NHibernateRepository(ISession session)
{
_session = session;
}
public T Load<T>(Guid id)
{
return _session.Load<T>(id);
}
public T Get<T>(Guid id)
{
return _session.Get<T>(id);
}
public void Save<T>(T obj)
{
_session.SaveOrUpdate(obj);
}
public void Delete<T>(T obj)
{
_session.Delete(obj);
}
//Get all T
public IEnumerable<T> Matching<T>() where T : DomainObject
{
return _session.CreateCriteria<T>().List<T>();
}
//NHibernate 3.0 Linq
public IQueryable<T> Matching<T>(Expression<Func<T, bool>> predicate)
{
return _session.Query<T>().Where(predicate);
}
public IEnumerable<T> Matching<T>(ICreateCriteria<T> query, params IAppendCriterion[] extraCriterias)
{
var criteria = query.GetCriteria();
foreach (var criterion in extraCriterias)
{
criterion.Append(criteria);
}
return criteria.GetExecutableCriteria(_session).List<T>();
}
}
最后一个方法接受ICreateCritiera实现。下面是界面和它的一个实现。
public interface ICreateCriteria<T> : ICreateCriteria
{
DetachedCriteria GetCriteria();
}
public class ChallengesAvailableToRound : ICreateCriteria<Challenge>
{
private readonly Guid _roundId;
public ChallengesAvailableToRound(Round round)
{
_roundId = round.Id;
}
public DetachedCriteria GetCriteria()
{
var criteria = DetachedCriteria.For<Challenge>().
CreateAlias("Event", "e").
CreateAlias("e.Rounds", "rounds").
Add(Restrictions.Eq("rounds.Id", _roundId));
return criteria;
}
}
这让我可以将查询分解为自己的类,并轻松地在我的项目中重复使用它们。
答案 2 :(得分:0)
我找到了你应该使用Repository / DAO / Whatever的一些原因。
这是知道的,不记得别的。