将数据上下文从工作单元传递到存储库
本文关键字:存储 单元 数据 上下文 工作 | 更新日期: 2023-09-27 18:12:23
我使用存储库进行数据访问已有一段时间了,但从未成功实现过类似于工作单元模式的任何东西。我开始了一个使用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会话中。所有这些都让我有点不舒服;在整个工作单元的概念中,我是不是漏掉了什么关键的东西?
我不喜欢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();
}
这两种方法我都不喜欢;在我收到更好的建议之前,我会把这个标记为答案。
Julia Lerman有一些使用实体框架的工作单元的好例子。
在实体框架中,上下文支持它,因此实现一个工作单元非常容易。我认为主要的问题是你们如何管理订单。示例:表A和表B
表B有一个指向表a的外键。你的功单位必须知道如何排序,否则就会出错。我会选择OR/M,比如Nhibernate或EF。这会让事情变得简单很多