NHibernate QueryOver выбирает объект и агрегаты

Что я хочу сделать, так это отобразить простую сетку данных, содержащую данные объекта и совокупные данные его дочерних элементов. Например, давайте использовать заказ и позиции. Я хочу отобразить информацию о заказе и количество позиций.

OrderID, OrderDate, NumOfLineItems

Теперь обычно в SQL вы можете сделать это разными способами. Но это единственный способ, который я мог придумать, который мог бы работать при переводе на NHibernate.

SELECT o.OrderID, OrderDate, NumOfLineItems
FROM #Orders o
INNER JOIN
(SELECT o2.OrderID, COUNT(*) As NumOfLineItems FROM #LineItems l
INNER JOIN #Orders o2 ON o2.OrderID = l.OrderID
WHERE UserID = 1 GROUP BY o2.OrderID) t1 ON o.OrderID = t1.OrderID
WHERE UserID = 1

Я знаю, что есть и другие способы, но я пытаюсь придумать, как NHibernate позволит мне использовать синтаксис QueryOver. Я не хочу использовать производные столбцы. Я пытаюсь избежать написания SQL.

Для моих сущностей у меня есть сущность Order и сущность AggregatedOrder, которая в данном случае будет моим DTO, и я планирую использовать aliastobean-преобразователь для копирования данных в нее.

Я просто совершенно не представляю, как это понять.

Все, что у меня есть на данный момент:

        QueryOver<LineItem> x = QueryOver.Of<LineItem>()
            .SelectList(p => p .SelectCount(l => l.Id).WithAlias(() => itemAlias.NumOfLineItems))
            .JoinQueryOver<Order>(l => l.Order)
            .Where(o => o.UserID == userID)


        var y = session.QueryOver<Listing>()
            .JoinQueryOver<Bid>(x); // no idea whats going on here

person BradLaney    schedule 23.06.2011    source источник


Ответы (1)


Данный:

public class Order
{
    public virtual int OrderId {get; set;}
    public virtual DateTime OrderDate {get; set;}
    public virtual IList<LineItem> LineItems {get; set;}
}
public class LineItem
{
    public virtual int Id {get; set;}
    public virtual string Description {get; set;}
}

Чтобы запросить проекцию Order + Aggregated LineItem с помощью QueryOver API, вы можете сделать следующее:

OrderDto orderDto = null;
LineItem items = null;
var results = session.QueryOver<Order>()
     .JoinAlias(o => o.LineItems, () => items)
     .Select(Projections.ProjectionList()
      .Add(Projections.Property<Order>(o=>o.Id).WithAlias(()=>orderDto.OrderId))
      .Add(Projections.Property<Order>(o=>o.DateOrdered).WithAlias(()=>orderDto.DateOrdered))
      .Add(Projections.Count(()=> items.Id).WithAlias(()=>orderDto.ItemCount))
     )
     .TransformUsing(Transformers.AliasToBean<OrderDto>())
    .List<OrderDto>();
person Mark Perry    schedule 30.06.2011
comment
Что ж, это обескураживает. Необходимость указывать каждый столбец будет кошмаром =) - person BradLaney; 30.06.2011
comment
@ user745537 Да, я могу поверить, что это будет больно. Я посмотрю, смогу ли я найти какое-либо другое решение. - person Mark Perry; 30.06.2011
comment
@ user745537 У меня было время подумать об этом, и я не знаю, как сделать то, что вы хотите. Другим возможным решением было бы использование двух запросов (один для сущностей, один для совокупного количества) и объединение их вместе в памяти с помощью LINQ. - person Mark Perry; 01.07.2011