我有一个NHibernate会话。在此会话中,我正在执行1个操作,即运行此代码以获取列表:
public IList<Customer> GetCustomerByFirstName(string customerFirstName)
{
return _session.CreateCriteria(typeof(Customer))
.Add(new NHibernate.Expression.EqExpression("FirstName", customerFirstName))
.List<Customer>();
}
我在Session.Flush()
的末尾打电话给HttpRequest
,我得到HibernateAdoException
。 NHibernate将更新语句传递给db,并导致外键违规。如果我不运行flush
,则请求完成没有问题。这里的问题是我需要刷新,以防在其他会话中发生更改,因为此代码在其他区域中重用。是否有其他配置设置我可能会丢失?
以下是例外代码:
[SQL: UPDATE CUSTOMER SET first_name = ?, last_name = ?, strategy_code_1 = ?, strategy_code_2 = ?, strategy_code_3 = ?, dts_import = ?, account_cycle_code = ?, bucket = ?, collector_code = ?, days_delinquent_count = ?, external_status_code = ?, principal_balance_amount = ?, total_min_pay_due = ?, current_balance = ?, amount_delinquent = ?, current_min_pay_due = ?, bucket_1 = ?, bucket_2 = ?, bucket_3 = ?, bucket_4 = ?, bucket_5 = ?, bucket_6 = ?, bucket_7 = ? WHERE customer_account_id = ?]
没有参数显示为传递。
答案 0 :(得分:45)
每当处理NHibernate时,都要小心使用NULLable字段。如果您的字段在DB中为NULL,请确保相应的.NET类也使用Nullable类型。否则,会发生各种奇怪的事情。症状通常是NHibernate将尝试更新DB中的记录,即使您从数据库中读取实体后没有更改任何字段。
以下序列解释了为什么会发生这种情况:
这不仅会损害性能(每次检索实体时都会获得额外的数据库往返和额外更新),但这也可能导致很难使用DateTime列来解决错误。实际上,当DateTime属性初始化为其默认值时,它设置为1/1/0001。当此值保存到DB时,ADO.NET的SqlClient无法将其转换为有效的SqlDateTime值,因为可能的最小SqlDateTime是1/1/1753 !!!
最简单的解决方法是使类属性使用Nullable类型,在本例中为“DateTime?”。或者,您可以通过实现IUserType及其Equals方法来正确地比较DbNull.Value与值类型的任何默认值来实现自定义类型映射器。在我们的例子中,当将1/1/0001与DbNull.Value进行比较时,Equals需要返回true。实现一个功能齐全的IUserType并不是那么难,但它确实需要NHibernate琐事的知识,所以如果你选择这样做,准备做一些实质性的谷歌搜索。
答案 1 :(得分:16)
之前我曾经看过一次我的模型之一没有正确映射(没有正确使用可空类型)。请你粘贴模型和贴图吗?
答案 2 :(得分:0)
当我尝试使用access =“noop”隐藏多对多行李的反向末端时,我也在NH 2.0.1中遇到过这个问题(提示:这不起作用)。
将它们转换为access =“field”+在类上添加一个字段修复了问题。虽然很难追踪它们。