我正在开发的项目有一个遗留数据库,其中包含大量用于改变应用程序行为的信息。基本上我会遇到一些事情,我必须超级小心改变。
解决我的问题。在这个数据库中是一个表,在这个表中是一列。此列包含整数,并且此列的大多数预先存在的数据的值为零。
问题是这个列实际上是另一个实体的外键引用,它在数据库模式中从未被定义过。
现在在我的新代码中,我定义了我的Fluent-NHibernate映射,将此列视为Reference,这样我就不必直接在代码中处理实体id。这工作正常,直到我遇到此列中值为0的实体。
NHibernate认为值为0是有效的引用。当我的代码尝试使用该引用的对象时,我得到一个ObjectNotFoundException,因为我的数据库中没有id为0的对象。
我如何通过映射或某种约定(我使用Fluent-nhibernate),让NHibernate处理0的id,就像它是NULL一样?
答案 0 :(得分:1)
我发现API告诉NHibernate忽略未找到的引用(NotFound.Ignore()),而不是抛出异常。我对在网上发现的SetAttribute()的所有提及感到困惑,这是一个比我使用的旧版本的流利的nhibernate。
答案 1 :(得分:0)
我处于同样的境地。 not-found = ignore的问题是,每次尝试访问它时它都会重新查询该关系,即使它已经在原始查询中运行了。基本上,hibernate没有存储关系中其他方面没有记录的事实。您可以在调试日志中看到这一点。这是我当前项目的一个例子。
loading entity:
attempting to resolve:
object not resolved in any cache:
Fetching entity:
loading entity:
Opened new IDbCommand, open IDbCommands: 1
Building an IDbCommand object for the SqlString: SELECT townshipdo0_.TOWNSHIP_CODE as TOWNSHIP1_203_0_, townshipdo0_.TOWNSHIP_NAME as TOWNSHIP2_203_0_, townshipdo0_.TOWNSHIP_TYPE_CODE as TOWNSHIP3_203_0_, townshipdo0_.TOWN_ACTIVE_FLAG as TOWN4_203_0_, townshipdo0_.VERS as VERS203_0_ FROM VTTOW_TOWN_CODE townshipdo0_ WHERE townshipdo0_.TOWNSHIP_CODE=?
binding ' ' to parameter: 0
SELECT townshipdo0_.TOWNSHIP_CODE as TOWNSHIP1_203_0_, townshipdo0_.TOWNSHIP_NAME as TOWNSHIP2_203_0_, townshipdo0_.TOWNSHIP_TYPE_CODE as TOWNSHIP3_203_0_, townshipdo0_.TOWN_ACTIVE_FLAG as TOWN4_203_0_, townshipdo0_.VERS as VERS203_0_ FROM VTTOW_TOWN_CODE townshipdo0_ WHERE townshipdo0_.TOWNSHIP_CODE=:p0
你可以看到它试图绑定'',这个应用程序的数据库使用空格来表示null(我知道这是愚蠢的)。但每次nhibernate遇到这种情况时,都会尝试从数据库中查找它,因为它无法在缓存中找到记录,也不知道它实际上是NULL。
如果我们可以在配置中指定要忽略的默认空值,那就太好了。目前解决这个问题的唯一方法是使用查询来加载你的关系,而不是依赖于nhibernate生成的查询。