HQL и Session.Query игнорируют активное получение, определенное в отображении - PullRequest
0 голосов
/ 20 января 2012

У меня проблема с тем, что NHibernate не использует мою конфигурацию сопоставлений для быстрой загрузки коллекции, когда я получаю что-то с помощью HQL или Linq (Session.Query). Session.Get и Session.QueryOver работают как ожидалось.

Я использую NHibernate 3.2. Вот отображение коллекции в моем отображении продукта.

<bag name="OrderItems" inverse="true" cascade="none" lazy="false" fetch="join">
  <key column="order_id" />
  <one-to-many class="OrderItem" />
</bag>

и с другой стороны отображение выглядит так:

<many-to-one name="Product" class="Product" column="product_id" not-null="true" />

У меня 4 теста, 2 успешных и 2 нет. Они используют Session.SessionFactory.Statistics для отслеживания CollectionFetchCount (был выбран OrderItems в 1 объединенном запросе или в отдельном). Намерение состоит в том, чтобы выбрать и загрузить OrderItems при выборе продукта, поскольку к OrderItems также почти всегда осуществляется доступ.

LastCreated - это простая ссылка на последний продукт, вставленный в БД.

[Test] /* Success */
public void Accessing_Collection_Using_Session_Get_Results_In_1_Select()
{

    // Get by Id
    var product = Session.Get<Product>(LastCreated.Id);
    var count = product.OrderItems.Count;
    Assert.AreEqual(0,statistics.CollectionFetchCount,"Product collectionfetchcount using Get");
}


[Test] /* Success */
public void Accessing_Collection_Using_Session_QueryOver_Results_In_1_Select()
{

    // Get by Id
    var product = Session.QueryOver<Product>().SingleOrDefault();
    var count = product.OrderItems.Count;
    Assert.AreEqual(0, statistics.CollectionFetchCount, "Product collectionfetchcount using QueryOver");
}
[Test] /* Fail */
public void Accessing_Collection_Using_Session_Query_Results_In_1_Select()
{

    // Get by IQueryable and Linq
    var product = Session.Query<Product>().Single(x => x.Id == LastCreated.Id);

    var count = product.OrderItems.Count;
    Assert.AreEqual(0, statistics.CollectionFetchCount, "Product collectionfetchcount using Linq");
}

[Test] /* Fail */
public void Accessing_Collection_Using_HQL_Results_In_1_Select()
{

    // Get by IQueryable and Linq
    var product = Session.CreateQuery("from Product where Id = :id")
        .SetParameter("id",LastCreated.Id)
        .UniqueResult<Product>();

    var count = product.OrderItems.Count;
    Assert.AreEqual(0, statistics.CollectionFetchCount, "Product collectionfetchcount using HQL");
}

Это предполагаемое поведение или я что-то не так делаю?

1 Ответ

6 голосов
/ 20 января 2012

HQL-запросы не будут соответствовать fetch="join", установленному в отображении.Это связано с тем, что они являются запросами произвольной формы, поэтому NH не может угадать, как их преобразовать, чтобы добавить объединение.

Linq реализован как оболочка для HQL, QueryOver - оболочка для критериев;вот почему вы видите различные варианты поведения.

Если вам нужны активные загрузки в Linq / HQL, вам придется сделать их явными в запросе (используя join fetch и Fetch()/FetchMany()

...