好吧,我有點難住這個NHibernate查詢。這個困惑在PasswordResetToken的周圍。NHIbernate「參考」屬性生成即使正確選擇+ 1外部連接
首先,這裏是映射:
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意味着JOIN使用子查詢代替,所以有沒有任何理由有額外的調用數據庫出現。
運行正確的SQL查詢返回保存聯繫人所需的所有信息,如NHProf(突出顯示的查詢)的屏幕截圖所示(不要擔心不同的表名等 - 我已對上面的代碼進行了清理):
我不明白的是爲什麼在地球上幾十個不同的選擇將PasswordResetToken表的生成和運行?其中一個查詢僅針對沒有PasswordResetToken的每個聯繫人生成(即第一個查詢返回這些列的空值) - 不確定這與它有什麼關係。
聯繫人可能有或可能沒有幾個角色(這個問題是多餘的),並且類似地,可能有也可能沒有恰好一個PasswordResetToken。
數據庫是有點狡猾與少數外鍵。在這種情況下,Contact和PasswordResetToken之間的鏈接是一個簡單的共享列「EmailAddress」。
所有這些查詢都是在上面單行代碼的運行過程中生成的(即代碼不在循環中)。
讓我知道我是否缺少任何信息。
我應該使用Google搜索嗎?
我今天也是自己打的!幽靈,我剛剛投票錯誤越多,我們得到更多的機會,可能會得到修復。 – Rippo 2013-03-20 16:41:08
謝謝傑米 - 從來沒有猜到它是一個錯誤。 – 2013-03-21 09:52:43