稍微修改数据模型后,某些查询开始给我这个例外。然而,即使在阅读了各种论坛主题和博客之后,我也不明白为什么会出现这种情况。所以我希望这里有人可以提供帮助。首先,一个示例查询:
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.
那么,为什么它不像上面显示的那样工作,并且当我删除查询的某些部分时它是否有效?
更新
生成的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 :(得分:0)
您的问题很可能源于这样一个事实,即如果您使用createalias(未指定外部联接类型),则无论您的配置是什么,都不会急切地加载实体。
这与您的错误相关的原因:假设您没有在关联的RHS上指定任何条件,并且您的数据中有空引用,则使用INNER JOIN会错误地过滤掉LHS上的记录。 / p>
因此,对于NHibernate,你的查询使用INNER JOINS返回两个结果并不重要,它继续前进,懒惰加载关联。在某处您可以引用多对多连接表中不存在的引用属性,并且当它尝试延迟加载它以检查RHS是否符合您的条件时它会失败。
更改别名以执行左外连接 应该防止错误(它实际上会急切地加载关联的实体而不是重新检查引用),但是你仍然会有参照完整性问题在某处:
criteria.CreateAlias("PublicProperty", "alias", JoinType.LeftOuterJoin);