NHIbernate“References”属性生成Select+1,即使外部连接正确
好吧,我有点被NHibernate的问题难住了。混淆之处在于PasswordResetToken 首先,这里是映射:NHIbernate“References”属性生成Select+1,即使外部连接正确,nhibernate,fluent-nhibernate-mapping,Nhibernate,Fluent Nhibernate Mapping,好吧,我有点被NHibernate的问题难住了。混淆之处在于PasswordResetToken 首先,这里是映射: public ContactMap() { Table("Contact"); Id(x => x.ContactId, "ContactId").Unique().GeneratedBy.Increment(); Map(x => x.EmailAddress); ... Map
public ContactMap()
{
Table("Contact");
Id(x => x.ContactId, "ContactId").Unique().GeneratedBy.Increment();
Map(x => x.EmailAddress);
...
Map(x => x.JobTitle);
References(x => x.PasswordResetToken, "EmailAddress")
.PropertyRef(x => x.EmailAddress)
.Cascade.None()
.Not.LazyLoad()
.Not.Update();
HasMany(x => x.Roles)
.Table("tblContactRole").KeyColumn("ContactId").Element("Role", part => part.Type<global::NHibernate.Type.EnumStringType<ContactRoles>>())
.AsSet()
.Not.LazyLoad();
}
现在是查询:
public IList<Contact> GetContacts(int id)
{
var contacts = Session.CreateCriteria<Contact>()
.Add(Restrictions.Eq("Id", id))
.Add(Restrictions.Eq("IsActive", true))
.SetFetchMode("Roles", FetchMode.Eager)
.SetFetchMode("PasswordResetToken", FetchMode.Eager)
.SetResultTransformer(CriteriaSpecification.DistinctRootEntity)
.List<Contact>();
return contacts;
}
我的理解是FetchMode.Eager意味着使用连接而不是子选择,因此没有任何理由显示对db的额外调用
运行一个正确的SQL查询,返回一个联系人所需的所有信息,如NHProf的屏幕截图所示。突出显示的查询不必担心不同的表名等-我已清理了上面的代码:
我不明白的是,为什么会生成并运行几十个单独的PasswordResetToken表选择??其中一个查询只为没有PasswordResetToken的每个联系人生成,即。第一个查询为这些列返回空值-不确定这与此有什么关系
联系人可能有或可能没有一些角色对此问题而言是多余的,同样,可能有或可能没有一个PasswordResetToken
数据库有点不可靠,外键很少。在本例中,Contact和PasswordResetToken之间的链接是一个简单的共享列EmailAddress
所有这些查询都是在运行ie上面的一行代码时生成的。该代码不在循环中
如果我丢失了任何信息,请告诉我
我应该在谷歌上搜索什么?这是一个很好的选择。我会尝试让它只处理两个查询,尽管从bug报告中听起来这将是一个挑战
附加的测试表明,引用唯一属性而不是Id的多对一关联会导致select n+1问题。尽管第一条语句包含正确的联接,但在联接选择之后,将逐个获取所有关联的实体。在unique列中具有相同值的实体甚至会被多次提取
有趣的是,只有在引用
实体已在会话缓存中。如果不是,则不是
将创建其他select语句
今天我自己也打了这个!诡异的是,我刚刚投了错误的票,所以我们得到的越多,它被修复的机会就越大。谢谢杰米-我从来没有想到它是一个错误。