正在寻找一种更简单的方法,Nhibernate和存储库
本文关键字:方法 Nhibernate 存储 更简单 一种 寻找 | 更新日期: 2023-09-27 18:22:06
这似乎是数据访问的一堆额外工作。我目前对非常基本的CRUD使用通用存储库,而且我有一些特定的存储库,在那里我可能需要急切地加载一些实体,以绕过可爱的N+1反模式。显然,没有N+1问题会让数据库感到高兴。下面是一个例子,说明我的想法。我想要一些反馈,也许还有更好的方式。
正如您从下面的代码中看到的,我的自定义存储库源自repository,我也有自定义存储库的接口。这一切对我来说似乎都错了。
public class EmailQueueRepository:Repository,IEmailQueueRepository
{
private readonly ISessionWrapper<ISession> _sessionWrapper;
public EmailQueueRepository(ISessionWrapper<ISession> sessionWrapper) : base(sessionWrapper)
{
_sessionWrapper = sessionWrapper;
}
public void AddEmailQueueItem(IEmailQueueItem queueItem)
{
_sessionWrapper.Session.CreateCriteria(typeof (EmailQueue)).SetFetchMode("User", FetchMode.Eager).SetFetchMode("EmailDeliveryStatus",FetchMode.Eager);
var emailQueueEntity = new EmailQueue
{
User = _sessionWrapper.Session.QueryOver<User>().Where(u=>u.UserId == queueItem.UserId).SingleOrDefault(),
ToAddress = queueItem.ToAddress,
Subject = queueItem.Subject,
MessageBody = queueItem.MessageBody,
EmailDeliveryStatus = _sessionWrapper.Session.QueryOver<EmailDeliveryStatus>().Where(x=>x.DeliveryStatus=="Pending").SingleOrDefault(),
Active = 1,
DateCreated = DateTime.Now,
LastUpdated = DateTime.Now
};
Insert(emailQueueEntity);
}
}
您觉得有什么问题?这基本上就是我所做的,除了:
- 我不包装ISession,而是让我的代码直接将ISession用于Save、Update、Get和Load操作以及控制事务。我的存储库保存预定义的查询,但应用程序可以自由地直接使用ISession
- 我将ISession公开为只读属性。这样就可以从现有的存储库中新建第二个存储库
- 我没有通用存储库。我将相关查询组合在一起,并将它们放在适当的存储库中。例如,检索Customer和CustomerStatus的查询都进入CustomerRepository,而不是每个类有一个存储库
这对我来说效果很好,其他开发人员也很容易理解。在我看来,使用存储库模式要避免的最大陷阱是有一个通用存储库,并且每个类有一个存储库。