您现在的位置: 365建站网 > 365文章 > Castle ActiveRecord 在查询时会自行更新数据库数据的问题

Castle ActiveRecord 在查询时会自行更新数据库数据的问题

文章来源:365jz.com     点击数:387    更新时间:2009-09-19 10:44   参与评论

    在使用AR过程中发现在查询数据时,有时会在后台出现数据库的update操作,对非字符串类型的字段,如果值为空,则更新为一个较小的值,如,int类型字段,自动更新为0,bit类型字段,自动更新为假。
    发现这个问题时,就分析是空属类型的问题,但又觉得不应该啊,update操作应该出现在对数据的更新或插入操作时,为什么会在查询时后台生成update语句来处理数据库呢?从网上查了一下资料,没有发现相关讨论,无意中发现了下面的这篇文章,觉得是类似的问题,只不过他遇到的是DateTime类型而已,就贴在了下面。
    经过把实体类的非字符串型的属性改为空属类型,就没有上述问题了。如:int?,bool?等。
    下面是看来的讨论类似问题的文章,关键的部分是最后一段。

NHibernate and the SqlTypeException

转自http://blog.jagregory.com/2007/12/18/nhibernate-and-the-sqltypeexception/

NHibernate is a wonderful piece of technology, I love it probably more than is reasonable for code. It does however, occasionally scare you with some seemingly odd behavior. I say seemingly, because every time I’ve had trouble it’s actually ended up being my own fault. This is one of those times.

Picture a simple page, with a DeleGrid control, being bound using NHiberate. Baring in mind how the DeleGrid works, two queries were being executed, one to return the first page of data and another to get the total row-count for the grid. These queries were identical apart from the paging in one, and the projection in the other.

Upon execution of the second query, NHibernate was throwing a SqlTypeException for a SqlDateTime overflow. SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM. This was pretty bizarre. Why on earth would the first query succeed (and bring back records, fully populated), but the same query again would die.

A good place to start for NHibernate debugging is always the logs, so I delved in. I discovered NHibernate was attempting to execute an update statement just before it tried the second query. It just kept getting stranger, why would a straightforward query cause an update?

I thought i’d investigate why the update statement was failing first, then I’d tackle the problem of why it was even updating at all. Looking at the query I identified the column that was causing the exception, it was (as expected) a DateTime column that was trying to be set to DateTime.MinValue. This exception is thrown because .Net and SQL Server have different ideas over what the minimum value for a DateTime should be.

Now, why would this column be being set at all? Well, it ends up that the column in the database was nullable, but the property in the object wasn’t. So because DateTime is a value type and cannot be set to null, NHibernate was populating it with the closest value to null as it could manage.

That was the key, as soon as I had that realisation, it was obvious what the problem was.

NHibernate knew that the database had a nullable column, but it had to manage with the non-nullable field on the object. When it came to run the second query, it noticed that the property wasn’t null as the mapping file said it should be, so it determined the value must have changed. It then attempted to persist those changes before executing the query!

To break it down

  1. Nullable column pulled into a non-nullable field forces NHibernate to create the smallest value it can.
  2. NHibernate then checks for any changes, expecting a null on that field but finding a value.
  3. Object now considered dirty because value has allegedly changed.
  4. NHibernate performs an update before it pulls back the data agian.

So the fix was simply to make the DateTime in the object a DateTime?, a nullable DateTime. That got rid of the false update, and fixed my queries. Simple when you know what the problem is.

So the moral of the story is: Make sure everything is in sync - schema, mappings and POCOs.

Tag标签: Castle

如对本文有疑问,请提交到交流论坛,广大热心网友会为你解答!! 点击进入论坛

发表评论 (387人查看0条评论)
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
昵称:
最新评论
------分隔线----------------------------

快速入口

· 365软件
· 杰创官网
· 建站工具
· 网站大全

其它栏目

· 建站教程
· 365学习

业务咨询

· 技术支持
· 服务时间:9:00-18:00
365建站网二维码

Powered by 365建站网 RSS地图 HTML地图

copyright © 2013-2024 版权所有 鄂ICP备17013400号