2

我对 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 位“转换”为 ac# 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 设置为“无”。
  2. 'IProject'-object 本身的基础数据基于 sql-view,因此映射中的大多数属性设置为 update="false"
  3. 当我实际更改对象中的某些内容并使用相同的保存方法时,正在发送 sql 更新语句(因此一切都很好)
4

2 回答 2

1

根据我的经验,鬼可能是由于数据库是 anullable 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"/>

请参阅此链接以测试您的映射,其中详细说明了。

于 2014-05-15T13:42:26.923 回答
0

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

于 2014-05-15T07:39:53.633 回答