nHibernate查询异常:不存在具有给定标识符的行

时间:2011-10-06 12:48:55

标签: 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.

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

更新

生成的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();

1 个答案:

答案 0 :(得分:0)

您的问题很可能源于这样一个事实,即如果您使用createalias(未指定外部联接类型),则无论您的配置是什么,都不会急切地加载实体。

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

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

更改别名以执行左外连接 应该防止错误(它实际上会急切地加载关联的实体而不是重新检查引用),但是你仍然会有参照完整性问题在某处:

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