nhibernate查询优化

时间:2011-05-24 12:36:41

标签: nhibernate linq-to-nhibernate

我有这个问题:

var resQuery = (from pan in session.Query<Pan>()
    orderby pan.AdnMonture.Marque.Nom select pan).ToList<Pan>();

Pan对象引用其他几个对象:

<many-to-one name="TypeMonture" column="IDType_Monture" cascade="save-update" not-null="true" />
<many-to-one name="AgeMonture" column="IDAge_Monture" cascade="save-update" not-null="true" />
<many-to-one name="SexeMonture" column="IDSexe_Monture" cascade="save-update" not-null="true" />
<many-to-one name="NatureMonture" column="IDNature_Monture" cascade="save-update" not-null="true" />
<many-to-one name="MatiereVerre" column="IDMatiere_Verre" cascade="save-update" />
<many-to-one name="TypeCouleurVerre" column="IDType_Couleur_Verre" cascade="save-update" />
<many-to-one name="CouleurVerre" column="IDCouleur_Verre" cascade="save-update" />
<many-to-one name="ClasseVerre" column="IDClasse_Verre" cascade="save-update" />
<many-to-one name="MontageMonture" column="IDMontage_Monture" cascade="save-update" not-null="true" />
<many-to-one name="BaseMonture" column="IDBase_Monture" cascade="save-update" not-null="true" />
<many-to-one name="CharniereMonture" column="IDCharniere_Monture" cascade="save-update" />
<many-to-one name="BrancheFormeMonture" column="IDBranche_Forme_Monture" cascade="save-update" />
<many-to-one name="BrancheEpaisseurMonture" column="IDBranche_Epaisseur_Monture" cascade="save-update" />
<many-to-one name="TenonPositionMonture" column="IDTenon_Position_Monture" cascade="save-update" not-null="true" />
<many-to-one name="TenonTailleMonture" column="IDTenon_Taille_Monture" cascade="save-update" not-null="true" />
<many-to-one name="FormeMonture" column="IDForme_Monture" cascade="save-update" not-null="true" />

我有时需要获得每个项目的价值,例如:

foreach (var pan in resQuery)
{
  var test = pan.TypeMonture.Name
  // and more ...
}

我有时会在该查询中产生大约100个结果,并且我可以对此单页进行大约1k的查询。 有没有解决办法可以避免这种情况? (存储过程除外)

此致

修改

Mathieu解决方案有效,但我简化了示例的案例。 我有这个错误:

A fetch request must be a simple member access expression of the kind o => o.Related; 'pan.Adn.Fabricant' is too complex.
Nom du paramètre : relatedObjectSelector

我的Pan对象引用Adn对象。

<many-to-one name="AdnMonture" column="IDADN_Mont" cascade="save-update" not-null="true" />

此Adn对象引用我之前呈现的所有数据。 (参见之前的hbm.xml)

这种情况还有其他解决方案吗? 也许加入?

修改2

我尝试使用ThenFetch

return (from pan in session.Query<PanierMonture>()
  .Fetch(pan => pan.AdnMonture)
  .ThenFetch(adn => adn.Fabricant)
  .ThenFetch(adn => adn.Reference)
  .ThenFetch(adn => adn.Marque)
  orderby pan.AdnMonture.Marque.Nom
  select pan).ToList<PanierMonture>();

第一个ThenFirst工作 但第二个被智慧所阻挡。 我使用Fabricant对象。 所以我试了一下:

return (from pan in session.Query<PanierMonture>()
  .Fetch(pan => pan.AdnMonture)
  .ThenFetch(adn => adn.Fabricant)
  .Then(adn => adn.Reference)
  .Then(adn => adn.Marque)
  orderby pan.AdnMonture.Marque.Nom
  select pan).ToList<PanierMonture>();

但是它再次起作用。 intellisense不给我adn对象

我发现了这个解决方法:

        return (from pan in session.Query<PanierMonture>()
                .Fetch(pan => pan.AdnMonture)
                .ThenFetch(adn => adn.Fabricant)
                .Fetch(pan => pan.AdnMonture)
                .ThenFetch(adn => adn.Marque)
                .Fetch(pan => pan.AdnMonture)
                .ThenFetch(adn => adn.Reference)
                .Fetch(pan => pan.AdnMonture)
                .ThenFetch(adn => adn.Coloris)
                .Fetch(pan => pan.AdnMonture)
                .ThenFetch(adn => adn.TailleMonture)
                orderby pan.AdnMonture.Marque.Nom
                select pan).ToList<PanierMonture>();

这是对的吗? 生成的sql查询有点奇怪:

select ..... from Panier_Monture paniermont0_ left outer join ADN_Monture adnmonture1_ on paniermont0_.IDADN_Mont=adnmonture1_.IDADN_Monture left outer join Fabricant fabricant2_ on adnmonture1_.IDFabricant=fabricant2_.IDFabricant left outer join ADN_Monture adnmonture3_ on paniermont0_.IDADN_Mont=adnmonture3_.IDADN_Monture left outer join Marque marque4_ on adnmonture3_.IDMarque=marque4_.IDMarque left outer join ADN_Monture adnmonture5_ on paniermont0_.IDADN_Mont=adnmonture5_.IDADN_Monture left outer join Reference reference6_ on adnmonture5_.IDReference=reference6_.IDReference left outer join ADN_Monture adnmonture7_ on paniermont0_.IDADN_Mont=adnmonture7_.IDADN_Monture left outer join Coloris coloris8_ on adnmonture7_.IDColoris=coloris8_.IDColoris left outer join ADN_Monture adnmonture9_ on paniermont0_.IDADN_Mont=adnmonture9_.IDADN_Monture left outer join Taille_Monture taillemont10_ on adnmonture9_.IDTaille=taillemont10_.IDTaille left outer join ADN_Monture adnmonture11_ on paniermont0_.IDADN_Mont=adnmonture11_.IDADN_Monture left outer join Marque marque12_ on adnmonture11_.IDMarque=marque12_.IDMarque order by marque12_.Nom asc

AdnMonture表每次重复一次? 有可能出现问题吗?

关心并再次感谢你

1 个答案:

答案 0 :(得分:4)

请参阅此答案:Eager load while using Linq in NHibernate 3

var resQuery = (from pan in session.Query<Pan>()
    .Fetch(p => p.TypeMonture)
    .Fetch(p => p.AgeMonture)
    .Fetch(p => p.Adn ).ThenFetch( a => a.Fabricant )// .. etc
orderby pan.AdnMonture.Marque.om select pan).ToList<Pan>();

现在您的链接实体将被提取,您将不会遇到SELECT N + 1问题