为什么我在第一次尝试插入数据时从数据库中收到错误后才插入模型:
Report report = null;
using (var session = SessionFactory.OpenSession()) {
try {
using (var transaction = session.BeginTransaction()) {
report = new Report();
session.SaveOrUpdate(report);//Exception: Name field required
transaction.Commit();
}
}
catch { }
try {
using (var transaction = session.BeginTransaction()) {
report.Name = "theName";
session.SaveOrUpdate(report);
//Causes Exception:
//Row was updated or deleted by another transaction (or unsaved-value
//mapping was incorrect): [ReportViewer.DataAccess.Models.Report#22]
transaction.Commit();
}
}
catch { }
}
但是当我更新现有模型时,我收到错误,我可以进行修复(在这种情况下设置一个名称)并尝试再次更新:
Report report = null;
using (var session = SessionFactory.OpenSession()) {
using (var transaction = session.BeginTransaction()) {
report = new Report();
report.Name = "theName";
session.SaveOrUpdate(report);
transaction.Commit();
}
}
using (var session = SessionFactory.OpenSession()) {
//get entity saved from previous session
report = session.Get<Report>(report.Id);
try {
using (var transaction = session.BeginTransaction()) {
report.Name = null;
session.SaveOrUpdate(report);//Exception: Name field required
transaction.Commit();
}
}
catch { }
try {
using (var transaction = session.BeginTransaction()) {
//updates and does not give an error
report.Name = "theName";
session.SaveOrUpdate(report);
transaction.Commit();
}
}
catch { }
}
答案 0 :(得分:4)
当数据库触发异常时,必须关闭(处置)NHibernate会话。在异常之后,不保证它是一致的(内部或DB状态)。
答案 1 :(得分:2)
正如Oskar所说,你应该在异常发生后丢弃一个NHibernate会话。但是,插入失败的原因是您已经通过在其上调用SaveOrUpdate
来保持报告的持久性(您应该在此使用Save
)。当您在同一个实例上再次调用SaveOrUpdate
时,NHibernate会抛出异常,因为该对象已经是持久的。如下重写代码可能会允许插入成功(但不建议这样做):
try {
using (var transaction = session.BeginTransaction()) {
report.Name = "theName";
transaction.Commit();
}
}
在更新示例中,调用SaveOrUpdate
没有任何效果,因为当NHibernate加载它时对象变得持久。理解NHibernate的instance states以及如何work with persistent objects是基本的,并且被广泛误解。
更好的方法是在将对象保存到数据库之前验证它们。