我对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:我还应该提到这些方面:
答案 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”。