Nhibernate - eager fetchmode, external join - предложение Order для коллекции вызывает второй ненужный запрос - PullRequest
1 голос
/ 01 февраля 2012

Когда я запускаю следующий код с одним запросом, чтобы получить 3 коллекции для Продукта: прайс-лист, Материалы и Цвета. И когда product.PriceList получает доступ к коллекции, у меня есть данные

ProductDTO Product = (ProductDTO)session.CreateCriteria(typeof(ProductDTO))
                .Add(Expression.IdEq(code))
                .SetFetchMode("Colors", FetchMode.Eager)
                .SetFetchMode("PriceList", FetchMode.Eager)
                .SetFetchMode("Materials", FetchMode.Eager)
                .UniqueResult();

Проблема в том, что мне нужно перечислить коллекцию PriceList по порядку по Num, и я использую следующий код:

ProductDTO Product = (ProductDTO)session.CreateCriteria(typeof(ProductDTO))
                .Add(Expression.IdEq(code))
                .SetFetchMode("Colors", FetchMode.Eager)
                .SetFetchMode("PriceList", FetchMode.Eager)
                .SetFetchMode("Materials", FetchMode.Eager)
                .UniqueResult();

ИЛИ следующий код:

ProductDTO Product = (ProductDTO)session.CreateCriteria(typeof(ProductDTO))
                .Add(Expression.IdEq(code))
                .SetFetchMode("Colors", FetchMode.Eager)
                .SetFetchMode("PriceList", FetchMode.Eager)
                .SetFetchMode("Materials", FetchMode.Eager)
                .CreateCriteria("PriceList").AddOrder(Order.Asc("Num"))
                .UniqueResult();

Это ограничение означает, что, когда я получаю доступ к продукту коллекции. PriceList FORCE НОВЫЙ ЗАПРОС на PriceList (не с пунктом заказа), который не нужен. И иногда я получаю сообщение «Не удалось лениво инициализировать роль сбора, ни один сеанс или сеанс не был закрыт»

Пожалуйста, если кто-нибудь может мне помочь. Мне нравится решать в одном запросе и понимать, что происходит. Я нашел похожий пост, как тот, который использует "not-found = ignore". Я использую NHIBERNATE 2.1.2

Я воспроизвожу ниже часть отображений:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
    <class name="DotAR.M.Logica.DTO.ProductDTO, DotAR.M" table="products">
        <id name="Code" type="string" unsaved-value="null">
            <generator class="assigned" />
       </id>
       <set name="PriceList" lazy="true" inverse="true" cascade="all">
            <key column="code" />
            <one-to-many class="DotAR.M.Logica.DTO.ProductPriceNumDTO, DotAR.M" />
       </set>

       <set name="Colors" lazy="true" inverse="true" cascade="all">
            <key column="code" />
            <one-to-many class="DotAR.M.Logica.DTO.ProductColorDTO, DotAR.M" />
       </set>
       <set name="Materials" lazy="true" inverse="true" cascade="all">
            <key column="code" />
            <one-to-many class="DotAR.M.Logica.DTO.ProductMaterialDTO, DotAR.M" />
       </set>
    </class>
</hibernate-mapping>

Каждая коллекция имеет составной идентификатор. Пример ProductColor

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
   <class name="DotAR.M.Logica.DTO.ProductColorDTO, DotAR.M" table="product_colors">
        <composite-id unsaved-value="any">
            <key-property name="Code" type="string" />
            <key-property name="Name" type="string" />
        </composite-id>
        <many-to-one name="Product" column="code" class="DotAR.M.Logic.DTO.ProductDTO, DotAR.M" insert="false" update="false" />
 </class>
</hibernate-mapping>

1 Ответ

1 голос
/ 06 февраля 2012

.CreateCriteria("PriceList").AddOrder(Order.Asc("Num")) -> NH применяет заказ к ProductDTO.Num.

В противном случае это в основном noop. Так как PriceList - это набор, который не имеет порядка, даже отсортированные результаты из базы данных получат несортированные клиентские данные. Что вы, вероятно, хотите, это:

// using linq
var orderedPrices = Product.PriceList.Ordery(price => price.Num).ToList();
...