【发布时间】:2014-07-02 12:57:42
【问题描述】:
我对 NHibernate 的 IsDirty() 方法有点困惑。
从我的数据库中获取一个(非常大的)复杂对象后,NHibernate 的 ISession.IsDirty() 直接给出“真”。
IFacadeDAL fd = new FacadeDAL();
// Session's not dirty
IProject proj = fd.GetByID<IProject, string>("123611-3640");
// Session is dirty
但是,如果我像这样调用 Commit():
using (ITransaction trans = Facade.Session.Transaction)
{
trans.Begin();
Facade.Session.Save(entity);
trans.Commit();
return true;
}
这会导致没有 sql(“exec sp_reset_connection”除外)。
我已经读到,由于“映射选择”,您可以在会话中获得“幽灵”(导致会话说它很脏),但它不会也尝试更新一些东西吗?此外,如果这是由于例如通过将 sql 位“转换”为 c# bool,我认为我无法更改它...(不过,不知道这是否会导致出现鬼魂)。
更新 2: 这里涉及到几个(sql server)视图和表。这是(非常)简化的类:
public class Project : IProject
{
private string id;
private List<IPlantItem> plantItems;
public Project() { }
public virtual string ID
{
get { return id; }
}
public virtual IEnumerable<IPlantItem> PlantItems
{
get { return plantItems; }
}
}
'PlantItem 正在存储在表中。所以我希望当我更改 PlantItem 中的任何内容时,IsDirty 应该更改为“true”。
我的问题是:有没有办法检查当时的会话是否会在 flush() 上(或者在我的情况下在 commit() 上)会生成实际的 sql 语句?如果没有:是否有另一种方式(手动)存储某种会话快照以与当前会话进行比较?
更新 1:我还真的应该提到这些方面:
- 我的 FlushMode 设置为“无”。
- 'IProject'-object 本身的底层数据基于 sql-view,因此映射集中的大多数属性设置为 update="false"
- 当我实际更改对象中的某些内容并使用相同的保存方法时,正在发送 sql 更新语句(因此一切都已提交)
【问题讨论】:
-
只是为了确定:您的
FlushMode是否设置为NONE?如果是的话:为什么你不在trans.Commit()之前打电话给session.Flush()? None 意味着永远不会调用 Flush。从来没有,也没有提交。 -
@Radim:Thnks Radim,但在这种情况下我使用 nh ITransaction,所以根据这个:nhforge.org/doc/nh/en/index.html#manipulatingdata-endingsession,我不必这样做。此外,所有其他功能都可以正常工作(提交更改和其他内容)。
-
你能不能有一个幽灵映射,让会话认为它很脏,但是因为你把它映射为
update="false",所以不会发送更新? -
阻止对视图的任何更新的肮脏技巧(我怀疑您有鬼)是将
<class name="Foo" table="foo_table" mutable="false">添加到您的类映射中 -
为什么将 mutable 设置为 false 是一个肮脏的 hack?我建议查看捉鬼敢死队测试并将其包含在您的测试服中。 joseoncode.com/2010/02/05/nhibernate-ghostbuster-version-1-1
标签: session nhibernate flush dirty-data