わかりました、私はこのNHibernateクエリに少し困惑しています。混乱はPasswordResetTokenに関するものです。
まず、マッピングは次のとおりです。
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は、SUBSELECTの代わりにJOINが使用されることを意味するため、dbへの追加の呼び出しが表示される理由はありません。
NHProfのスクリーンショット(強調表示されたクエリ)から明らかなように、連絡先をハイドレイトするために必要なすべての情報を返す正しいSQLクエリが実行されます(異なるテーブル名などについて心配する必要はありません-上記のコードをサニタイズしました):
私が理解していないのは、なぜPasswordResetTokenテーブルへの数十の個別の選択が生成されて実行されるのですか?これらのクエリの1つは、PasswordResetTokenを持たないすべての連絡先に対してのみ生成されます(つまり、最初のクエリはそれらの列に対してnullを返します)-これがそれと何の関係があるのかわかりません。
連絡先にはいくつかの役割がある場合とない場合があり(この問題には不要)、同様に、PasswordResetTokenが1つだけある場合とない場合があります。
DBは少し危険で、外部キーがほとんどありません。この場合のContactとPasswordResetTokenの間のリンクは、単純な共有列「EmailAddress」です。
これらのクエリはすべて、上記の1行のコードの実行時に生成されます(つまり、そのコードはループ内にありません)。
情報が不足している場合はお知らせください。
何をグーグルする必要がありますか?