我一直在使用存储库进行数据访问已有一段时间了,但从未成功实现类似于工作单元模式的任何内容。我已经开始使用RavenDB和ASP.NET MVC进行自我教育的新项目(理论上这些细节应该是微不足道的),我希望建立一个包装业务交易的好方法(不 web)要求)在他们自己的工作单位,但我有一些困难。
以下代码段是我喜欢的内容:
public class UserService : IUserService
{
private readonly IRepository<User> _userRepository;
private readonly IRepository<Role> _roleRepository;
public UserService(
IRepository<User> userRepository,
IRepository<Role> roleRepository)
{
_userRepository = userRepository;
_roleRepository = roleRepository;
}
public void Register(User user)
{
using (var session = UnitOfWork.Begin())
{
_userRepository.Create(user);
_roleRepository.AddToRole(user, Role.Public);
session.Commit();
}
}
}
我对工作单元界面的第一次尝试看起来像这样:
public interface IUnitOfWork : IDisposable
{
void Commit();
}
public class UnitOfWork : IUnitOfWork
{
private readonly IDocumentSession _session;
public UnitOfWork(IDocumentStore documentStore)
{
_session = documentStore.OpenSession("http://from:config");
}
public void Commit()
{
_session.SaveChanges();
}
public static IUnitOfWork Begin()
{
return IoC.GetInstance<IUnitOfWork>();
}
public void Dispose()
{
_session.Dispose();
}
}
我遇到的是存储库对数据库会话的访问。正如我所提到的,我想将商业交易包装在自己的单位中;我也不热衷于将会话/上下文传递给每个方法,而我见过的大多数其他解决方案都使用静态方法和/或存储在Web会话中。所有这些让我有点不舒服;在整个工作单元概念中,我是否缺少一些关键点?
答案 0 :(得分:1)
我不喜欢TransactionScope
的概念,还有进一步的研究和进展。讨论让我相信我想做的事情根本不可行。
最后,UnitOfWork
上下文中的存储库需要(明确地)了解UnitOfWork
。我还没有确定要走哪条路,但我会做类似以下的事情:
using (var session = UnitOfWork.Begin())
{
_userRepository.Use(session).Create(user);
_roleRepository.Use(session).AddToRole(user, Role.Public);
session.Commit();
}
或
using (var session = UnitOfWork.Begin())
{
session.Get<IUserRepository>().Create(user);
session.Get<IRoleRepository>().AddToRole(user, Role.Public);
session.Commit();
}
我对这两种方法都不是很疯狂;在我收到更好的建议之前,我会将此标记为答案。
答案 1 :(得分:0)
Julia Lerman有一些使用实体框架的工作单元的很好的例子。
在实体框架中,它在上下文中得到支持,因此很容易实现一个工作单元。 我会看到的主要问题是你如何管理订单。 示例:表A和表B
表B具有表A的外键。 您的工作单元必须知道订购,否则会出错。 我会选择像Nhibernate或EF这样的OR / M. 它应该变得更容易。