2011-10-06 94 views
2

稍微修改了datamodel后,某些查询开始给我这个异常。但是,即使阅读了各种论坛主题和博客之后,我也不明白为什么会出现这种情况。所以我希望这里的某个人能够提供帮助。首先,例如查询:nHibernate查询异常:没有给定标识符的行

var criteria = Session.CreateCriteria(typeof(SomeEntity)); 
     criteria.Add(Expression.IdEq(id)); 
     criteria.SetFetchMode("_PrivateProperty", FetchMode.Eager); 
     criteria.CreateAlias("PublicProperty", "alias"); 
     criteria.Add(Expression.Eq("alias.Id", aliasId)); 

如果我修改通过删除(1)调用setFetchMode或(2)CreateAlias为公共财产查询,一切工作正常。

私有财产通常是懒惰地加载,但在这种情况下,我想加载它与其父实体一起对抗选择N + 1。

那么,为什么它不像上面显示的那样工作,并且当我删除查询的某些部分时它工作?

UPDATE

生成的SQL:

SELECT * FROM SomeEntity this_ 
inner join PublicProperty alias4_ on this_.SomeEntityId=alias4_.SomeEntityId 
inner join ReferencedProperty rp2_ on alias4_.RPId=rp2_.RPId 
left outer join PrivateProperty v1_ on this_.SomeEntityId=v1_.SomeEntityId 
WHERE this_.SomeEntityId= @p0 and rp2_.RPId= @p1 

当SQL Server Management Studio中运行,它按预期工作。我得到两个结果。在修改数据模型和查询之间,数据库中的数据没有改变。

UPDATE2

修改模型。 原始映射:

References(d => d.PublicProperty, "PublicPropertyId").Cascade.SaveUpdate(); 

新映射:

HasManyToMany(d => d.PublicPropertys) 
      .Access.CamelCaseField(Prefix.Underscore) 
      .Table("SomeEntityPublicProperty") 
      .ParentKeyColumn("SomeEntityId") 
      .ChildKeyColumn("PublicPropertyId") 
      .Cascade.SaveUpdate() 
      .Inverse(); 

UPDATE3

HasMany<PrivatePropertyEntity>(Reveal.Member<SomeEntity>("_PrivateProperty")) 
      .Table("SomeEntity_PrivateProperty") 
      .KeyColumn("SomeEntityId") 
      .Cascade.AllDeleteOrphan() 
      .LazyLoad().Inverse(); 
+0

生成的SQL看起来如何? – Firo

+0

您从未告诉我们您对数据模型进行了哪些更改。它与id数据类型有关吗? – dotjoe

+0

对不起,你是对的。我将'PublicProperty'从一对一修改为多对多(即引用 - >流利中的HasManyToMany)。该属性曾经是'SomeEntity'中定义的外键,但现在我有一个包含两者之间关系的附加表。 – Pieter

回答

0

你的问题可能来源于这样的事实,如果你使用createalias(不指定外连接类型)不管你的配置是什么,实体都不会被急切地加载。

这与您的错误相关的原因:假设您没有在关联的RHS中指定任何条件,并且数据中有空引用,则使用INNER JOIN会错误地过滤掉LHS上的记录。

因此,NHibernate无关紧要,你的查询返回两个使用INNER JOINS的结果,它继续前进,懒惰加载关联。某处您在多对多连接表中引用了一个不存在的引用属性,并且在尝试延迟加载它以检查RHS是否与您的条件匹配时失败。

更改别名进行左外连接应该防止错误(它实际上将急切地加载关联的实体,而不是重新检查的参考文献),但你仍然有参照完整性问题的地方:

criteria.CreateAlias("PublicProperty", "alias", JoinType.LeftOuterJoin); 
+0

mootinator,我查过了,但是每个实体都有关联的公共财产。这是预期的,因为他们曾经在非空列中的someentity表中。更改为LeftOuterJoin并未解决问题。 – Pieter

+0

这个问题不会是一个没有PublicProperty的实体,它会是'SomeEntityPublicProperty'中的一个记录,对'PublicProperty'有一个无效的引用。你有没有检查过(改变生成的SQL使用外部连接,并在条件中只使用'WHERE this_.SomeEntityId = @ p0' –

+0

您是否尝试过抑制此错误的常用方法?即添加'.NotFound.Ignore )''您的'ManyToMany'映射? –

相关问题