С NHibernate 2.1, как можно получить первый элемент в коллекции, используя HQL для использования в предложении select? - PullRequest
2 голосов
/ 31 марта 2011

Предположим, у меня есть класс Product:

public class Product
{
    public virtual string Name { get; set; }
    public virtual IList<Order> Orders { get; set; }
}

и класс Order:

public class Order
{
    public virtual float Amount { get; set; }
    public virtual DateTime Created { get; set; }
}

Предположим, что они сопоставлены (используя Fluent NHibernate) следующим образом:

public class ProductMap : ClassMap<Product>
{
    public ProductMap()
    {
        Map(x => x.Name);
        HasMany(x => x.Orders).OrderBy("created desc");
    }
}

public class OrderMap: ClassMap<Order>
{
    public OrderMap()
    {
        Map(x => x.Amount);
        Map(x => x.Created);
    }
}

Если бы я хотел получить Name Product, а также Amount последнего Order (который, благодаря моему отображенному предложению OrderBy, является первым) в HQLСкажите, как бы я поступил об этом?Примерно так (в иллюстративных целях):

select p.Name, p.Orders[0].Amount from Product p

Я пробовал много вариантов этого, каждый со своими собственными ошибками.

// Throws 'Property index does not exist in collection'
select p.Name, order.Amount from Product p join p.Orders as order where index(order) = 0

// Throws 'Antlr.Runtime.MismatchedTreeNodeException' on the brackets in p.Orders[0].
select p.Name, p.Orders[0] from Product P

// Throws 'Object reference not set to an instance of an object'
select p.Name, p.Orders[0].Amount from Product p

// Works fine, but not what I want
select p.name, order.Amount from Product p join p.Orders as order

В этом примере я мог уйтис использованием SetMaxResults(), но на самом деле запрос гораздо более сложный и возвращает много строк - так что это не сработает.

Мне кажется, что я здесь упускаю что-то элементарное, поэтому любая помощьприветствуется.

Использование: NHibernate 2.1.2.4000 и Fluent NHibernate 1.1.0.695

1 Ответ

1 голос
/ 31 марта 2011

Ну, это не отвечает на вопрос, можете ли вы получить элемент по его индексу в коллекции через HQL, но я нашел решение для своей реализации:

Мне нужно было либопервый или последний элемент в коллекции, и на помощь пришел подзапрос с агрегатными функциями min / max.@Mauricio заставил меня немного глубже задуматься об альтернативах в SQL, и пришел ответ:

select p.Name, order.Amount from Product p join p.Orders as order 
where order.Id = (select max(order2.Id) from Product p2 
join p2.Orders as order2 where p2.Id = p.Id)

Это не красиво, но оно делает свою работу.Надеюсь, это поможет кому-то еще ...

...