2011-05-24 56 views
0

我有此查询:NHibernate的查询优化

var resQuery = (from pan in session.Query<Pan>() 
    orderby pan.AdnMonture.Marque.Nom select pan).ToList<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个查询。 有没有解决方案可以避免这种情况? (比存储过程以外)

问候

编辑

的马修溶液的工作,但我简化的例子的情况。 而我有这个错误:

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 

我的平移对象引用一个Adn对象。

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

这个Adn对象引用了我之前介绍的所有数据。 (参见前面的hbm.xml)

这种情况下是否有其他解决方案? 也许与加入?

编辑2

我tryed使用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工作 但是第二次被intellisence阻止。 我使用了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>(); 

但它再次不起作用。智能感知不给我的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重复各次? 有问题吗?

问候,并再次感谢您

回答

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个问题

+0

谢谢马修的你的答案mathieu,它适用于我提出的案例,但不是真实的案例。我编辑了这个问题。 – 2011-05-24 13:16:07

+0

已更新的答案。使用“ThenFetch”。 – mathieu 2011-05-24 13:23:50