2012-01-26 13 views
1

私たちは複雑なビジネスモデルを持ち、NHibernateを使用してデータベースを作成および維持しています。これにより、かなりストレートなクエリによって大きなオブジェクトグラフが生成されるときに、パフォーマンスが低下することがあります。複数の単一選択を避け、NHibernateで複数選択を作成する方法

通常、私たちはクエリを書き直してパフォーマンスを向上させると同時に、ビジネスモデルをより良く知ることができます。しかし、今私たちは、私たちが現在持っているものが、率直に言えば、実際には本当に貧しいという良い結果を得ることができない場合を見つけました。

関連するマッピングを持つ次のクラスがあります。クラスは最小限に抑えられています。詳細が必要な場合は教えてください。

public class GraphPoint 
{ 
    public DateTime datum; 
    public IDictionary<Avtal, Value> values; 
    public Calculation calculation; 
    public bool isCalculated; 
    public Int64 graphPointId; 

    ... 
} 

public class Value 
{ 
    public int numbers; 
    public int points; 
} 

public class Avtal 
{ 
    public string name; 
    public Int64 avtalId 

    ... 
} 

<class name="GraphPoint" lazy="false"> 
    <id name="GraphPointId" column="GraphPointId" type="Int64"> 
    <generator class="Business.Data.IncrementGenerator, Business"/> 
    </id> 

    <property name="Datum" not-null="true" unique-key="UIX1_GraphPoint" /> 
    <map name="Values" table="GraphPointValue" cascade="all-delete-orphan"> 
    <key column="GraphPointId" foreign-key="FK_GraphPoint_GraphPointValue" /> 
    <map-key-many-to-many class="Avtal" column="AvtalId" 
          foreign-key="FK_GraphPoint_GraphPointValue_Avtal" /> 
    <composite-element class="GraphPoint+Value"> 
     <property name="Numbers" not-null="true" /> 
     <property name="Points" not-null="true" precision="26" scale="15" /> 
    </composite-element> 
    </map> 
    <property name="IsCalculated" not-null="true" /> 
    <many-to-one name="Calculation" column="CalculationId" 
       foreign-key="FK_Calculation_GraphPoint" /> 
</class> 

だから、このシナリオでは、私たち次のcriterias: は*二つの日付 間のすべてのGraphPointValuesを返す*はAvtalオブジェクト

に基づいてこれらを集約我々は現在、これにしようとしている:

from punkt in (from punkt in Session.Query<GraphPoint>() 
       where punkt.IsCalculated && 
        punkt.Datum >= lowDate && 
        punkt.Datum <= highDate 
       select punkt).ToArray() 
let values = from value in punkt.Values 
      where forAvtal.Contains(value.Key.AvtalId) 
      select value.Value 
select new GraphPointValuePresentationObject 
{ 
    Datum = punkt.Datum, 
    Numbers = värden.Sum(v => v.Antal), 
    Points = värden.Sum(v => v.Poäng), 
    IsCalculated = punkt.IsCalculated 
} 

forAvtalは、これらのオブジェクトに対応するIDを含むリストです。

これを実行すると、日付の間にあるすべてのGraphPointを取得したデータベースに対して1つのsql-statementを取得し、最初のsql-statementが返すポイントのそれぞれについて1つのsql-statmentを取得します。

これを書き直して、今日のようにいくつかの数百ものSQL文しか必要ないようにしたいと思います。誰も私に正しい方向のポインタを与えることができます、私はCritieriasとDetachedQueriesを試しましたが、私がしたいように動作するようにすることはできません。

答えて

1

を挿入する.Fetch(x => x.Values) befor .ToArray()はすべきことです。それは、グラフポイントと一緒にすべての関連値をフェッチする結合を生成します

+0

シンプルでありながら非常に複雑です、非常に感謝! –

関連する問題