2010-04-09 64 views
4

我正在处理的项目有一个遗留数据库,其中包含大量用于改变应用程序行为的信息。基本上我坚持的东西,我必须小心改变。NHibernate,遗留数据库,外键不是

对我的问题。在这个数据库中是一个表,在这个表中是一列。此列包含整数,并且此列中大多数已有数据的值为零。

问题是这个列实际上是另一个实体的外键引用,它在数据库模式中从未被定义为这样。

现在在我的新代码中,我定义了我的Fluent-NHibernate映射,将此列作为参考对待,以便我不必直接在我的代码中处理实体标识。这工作正常,直到我遇到一个实体在这个列中的值为0。

NHibernate认为值为0是一个有效的引用。当我的代码尝试使用该引用的对象时,我得到一个ObjectNotFoundException,因为显然没有对象在我的数据库中的ID为0.

我该如何通过映射或某种约定(我使用Fluent -nhibernate),得到NHibernate处理ID为0是相同的,如果它是NULL?

回答

1

我发现API告诉NHibernate忽略找不到的引用(NotFound.Ignore()),而不是抛出异常。我对所有提到的SetAttribute()我感到困惑,我在网上发现这是为了比我使用的流利-nhibernate更老的版本。

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 

你可以看到它尝试绑定',数据库为这个应用程序使用空的空间表示空(愚蠢的我知道)。但每次nhibernate遇到这种情况,它都会尝试从数据库中查找它,因为它无法在缓存中找到记录,也不知道它实际上是NULL。

如果我们可以在配置中指定要忽略的默认空值,那将会很不错。目前解决此问题的唯一方法是使用查询来加载您的关系,而不是依赖nhibernate生成的查询。