这个问题有点像傻瓜,但我仍然不明白处理潮红的最佳方法。
我正在迁移现有的代码库,其中包含许多代码,如下所示:
private void btnSave_Click()
{
SaveForm();
ReloadList();
}
private void SaveForm()
{
var foo = FooRepository.Get(_editingFooId);
foo.Name = txtName.Text;
FooRepository.Save(foo);
}
private void ReloadList()
{
fooRepeater.DataSource = FooRepository.LoadAll();
fooRepeater.DataBind();
}
现在我正在将FooRepository更改为Nhibernate,我应该将什么用于FooRepository.Save方法?在保存实体时,FooRepository是否应始终刷新会话?
答案 0 :(得分:3)
我不确定我是否理解你的问题,但这就是我的想法:
考虑“将对象放入会话”而不是“获取和存储数据”。 NH将在会话中存储所有新的和已更改的对象,而无需对其进行任何特殊调用。
考虑这种情况:
数据更改:
创建一个新对象:
如果使用分离的实体,还需要Update或SaveOrUpdate将分离的实体放入会话中。
当然,您可以将NH配置为具有不同的行为。但如果您遵循此默认行为,则效果最佳。
答案 1 :(得分:1)
无论是否在修改Foo实体和从存储库加载所有Foo之间显式刷新会话都无关紧要。如果您在会话中进行了可能影响您尝试运行的查询结果的更改,NHibernate非常智能,可以自动刷新自己。
理想情况下,我尝试每个“工作单元”使用一个会话。这意味着一个有凝聚力的工作,可能涉及几个较小的步骤。如果您觉得在您的体系结构中没有接缝可以实现此目的,那么管理存储库中的会话也将起作用。请注意,您错过了NHibernate为您提供的一些强大功能。
答案 2 :(得分:1)
如果可以的话,我会对Stefan Moser的回答进行投票 - 我自己仍在接触Nh,但我认为能够编写这样的代码真是太好了:
private void SaveForm()
{
using (var unitofwork = UnitOfWork.Start())
{
var foo = FooRepository.Get(_editingFooId);
var bar = BarRepository.Get(_barId);
foo.Name = txtName.Text;
bar.SomeOtherProperty = txtBlah.Text;
FooRepository.Save(foo);
BarRepository.Save(bar);
UnitOfWork.CommitChanges();
}
}
所以这样一来整个行动都成功了,或者它失败并回滚,将冲洗/交易管理保留在仓库之外。