Как избежать множественного одиночного выбора и создать множественный выбор с помощью NHibernate - PullRequest
1 голос
/ 26 января 2012

У нас сложная бизнес-модель, и мы используем 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>

Итак, в этом сценарии мы используем следующие критерии: * Возвращаем все значения GraphPointValues ​​между двумя датами * Агрегируем их на основе Avtalobject

В настоящее время мы пытаемся это сделать:

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 - это список, содержащий идентификаторы для этих объектов, которые должны быть выполнены.

Когда мы запускаем это, мы получаем один sql-оператор для базы данных, который выбирает все GraphPoints, которые лежат между датами, а затем мы получаем один sql-statment для каждой и каждой из точек, которые первый SQL-операторвозвращает.

Я хочу переписать это так, чтобы нам потребовалась только пара SQL-операторов, а не несколько сотен, как сегодня.Кто-нибудь может дать мне указатель в правильном направлении, я пробовал Critierias и DetachedQueries, но не могу заставить его работать так, как я хочу.

1 Ответ

1 голос
/ 26 января 2012

вставка .Fetch(x => x.Values) перед .ToArray() должна сработать. Он сгенерирует объединение для извлечения всех связанных значений вместе с Graphpoints

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...