NHibernate:如何知道Flush()SQL是否会被发送?

时间:2014-05-14 12:47:37

标签: session nhibernate flush dirty-data

我对NHibernate的IsDirty()方法感到有些困惑。

直接从我的数据库中获取(非常大)复杂对象后,NHibernate的ISession.IsDirty()给出'true'。

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”的exept)。

我已经读过,由于'映射选择'你可以在你的会话中得到“幽灵”(导致会话说它很脏),但它不会尝试更新某些内容吗?此外,如果这是由例如通过“转换”一个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:我还应该提到这些方面:

  1. 我的FlushMode设置为'None'。
  2. “IProject”对象本身的基础数据基于sql-view,因此映射集中的大多数属性都为update =“false”
  3. 当我实际更改对象中的某些内容并使用相同的方法进行保存时,正在发送sql update语句(因此所有提交都正常)

2 个答案:

答案 0 :(得分:1)

根据我的经验,Ghost可能是由数据库为nullable int而映射为普通int

当实体被水合时,nullable db int会转换为zero,因此它现在变脏了。

获取脏记录的另一种方法是在XML映射中指定错误的类型,例如,

public enum Sex
{
 Unspecified,
 Male,
 Female
}
...
public virtual Sex Sex { get; set; }

并在映射中指定一个int。

 <property name="Sex" type="int"/>

请参阅此link to test your mappings,其中详细说明了这一点。

答案 1 :(得分:0)

如果您的某些实体是脏的 - 因此ISession是脏的 - 它们在属性和数据库之间存在不匹配。例如,假设您在表中有一个可以为空的列,但在您的代码中,它被设置为非null(例如,int)。 NHibernate会认为它很脏,因为它的当前值(在整数的情况下为0)与来自db(null)的值不同。在Google中寻找“Ghost properties NHibernate”。