Asp.net mvc ASP.NET MVC、Nhibernate和中小型项目存储库
目前我正在从事一个小型ASP.NET MVC项目。Asp.net mvc ASP.NET MVC、Nhibernate和中小型项目存储库,asp.net-mvc,nhibernate,repository-pattern,Asp.net Mvc,Nhibernate,Repository Pattern,目前我正在从事一个小型ASP.NET MVC项目。 我正在尝试实现Nhibernate以在MS Sql Server数据库上持久化。 在花了很长时间研究DDD和互联网上的其他项目之后,我决定采用存储库模式。 现在我正面临一个两难选择。 使用Nhinbernate时,我真的需要存储库吗? 有一个服务层(我目前没有服务层)与Nhinbernate交互,避免多次编写类似的内容,不是更好吗 public Domain.Reminder GetById(Guid Code) { return (_
我正在尝试实现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);
}
公共域。提醒GetById(Guid代码)
{
返回(_session.Get(Code));
}
公共域。提醒LoadById(Guid代码)
{
返回(_session.Load(代码));
}
公共bool保存(域.提醒)
{
_会话。保存或更新(提醒);
返回(真);
}
公共bool删除(Domain.rements)
{
_删除(提醒);
返回(真);
}
我发现了一篇老Ayende的帖子,这篇帖子是针对存储库的。我知道围绕这些话题存在着巨大的争论,答案总是。。。视情况而定,但在我看来,抽象层次太多,事情变得更复杂,更难理解。
我错了吗?Ayende反对像您这样编写存储库,因为您提出这个问题的原因,它是重复的代码,NH可以以任何方式处理所有这些代码。他提倡直接调用NH,就像调用存储库一样,不要再担心它了
我非常同意他的看法。除了更多的工作之外,真的没有什么收获。我找到了一些你应该使用Repository/DAO/任何东西的理由
仅此而已,我不记得其他任何东西。请使用通用存储库。每个类一个存储库很容易被过度使用 我使用一个带有Get、Load、Save方法和各种匹配方法的存储库(一个用于Linq,一个用于我的域查询)
公共类NHibernateRepository:IRepository
{
专用只读会话;
公共NHibernateRepository(会议期间)
{
_会话=会话;
}
公共T加载(Guid id)
{
返回会话加载(id);
}
公共无法获取(Guid id)
{
return _session.Get(id);
}
公共作废保存(T obj)
{
_会话。保存或更新(obj);
}
公共作废删除(T obj)
{
_删除(obj);
}
//全力以赴
public IEnumerable Matching(),其中T:DomainObject
{
返回_session.CreateCriteria().List();
}
//NHibernate 3.0 Linq
公共IQueryable匹配(表达式谓词)
{
返回_session.Query().Where(谓词);
}
公共IEnumerable匹配(ICreateCriteria查询,参数IAppendCriteria[]extraCriterias)
{
var-criteria=query.GetCriteria();
foreach(标准外的var标准)
{
标准。附加(标准);
}
返回条件.GetExecutableCriteria(_session).List();
}
}
最后一个方法接受ICreatera实现。下面是接口和它的一个实现
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;
}
}
公共接口ICreateCriteria:ICreateCriteria
{
DetachedCriteria GetCriteria();
}
公共类挑战者可用ToRound:ICreateCriteria
{
专用只读Guid\u roundId;
公共挑战者可用环形(圆形)
{
_roundId=round.Id;
}
public DetachedCriteria GetCriteria()
{
var criteria=DetachedCriteria.For()。
CreateAlias(“事件”、“e”)。
CreateAlias(“e.Rounds”、“Rounds”)。
添加(Restrictions.Eq(“rounds.Id”,_roundId));
退货标准;
}
}
这使我能够将查询分解为它们自己的类,并在整个项目中轻松地重用它们 只是一张小纸条。没有中小型项目,它现在可以很小,但是明天你的经理会问你另一个特性,然后是另一个,最后你会有一个带有中小型架构的大型项目。我真的不喜欢大的设计,但有时你需要提前考虑一下。我完全同意你的观点,但是,如果不是因为我将来可能不使用nihbernate,我看不到使用repository的好处。它产生了很多额外的工作,我现在无法证明这一点。谢谢欧宁。我不想在控制器中编写查询,而是在服务层中编写查询。我认为这也是一个放置一些业务逻辑的好地方。它不会出现在UI中,如果我想在其他地方插入我的服务层,它将是可重用的。Nhibernate依赖性。嗯,是的,我可以同意,但我认为这不会很快发生,我也不认为这与更改存储库有什么不同。无论如何谢谢你。如果您模拟回购协议,您将使用“已知夹具”测试反模式。2.没有任何东西表明您不能在服务层中创建抽象。这是完全错误的。3.一点也不。你会给db打电话的。它是否在服务或repo方法调用或控制器的一部分中并不重要。还是一样的代码。控件
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;
}
}