NHibernate Использование соединения внутри подзапроса: не генерировать оператор соединения sql

У меня есть вызов с использованием QueryOver, который расположен следующим образом и не генерирует оператор внутреннего соединения, необходимый внутри подзапроса.

Структура объектов, которые я запрашиваю, выглядит следующим образом:

public class Product {
    public virtual long Id { get; set; }
    ... OTHER DATA MEMBERS ...
}

public class ProductListType1 {
    public virtual int Id { get; set; }
    public virtual DateTime Date { get; set; }
    public virtual char Category { get; set; }
    ... OTHER DATA MEMBERS ...
    public virtual IDictionary<short, Detail> Details { get; set; }

    public class Detail {
        public virtual short SequenceNumber { get; set; }
        public virtual ProductListType1 ProductListType1 { get; set; } // PARENT REFERENCE FOR BIDIRECTIONAL RELATIONSHIP
        public virtual Product Product { get; set; }
        ... OTHER DATA ...
    }
}


public class ProductListType2 {
    // SAME STRUCTURE AS PRODUCT LIST TYPE 1
}


ProductListType1.Detail detailAlias = null;
Product productAlias = null;

ProductListType2 productListType2Alias = null;
ProductListType2.Detail productListType2DetailAlias = null;

_session.QueryOver<ProductListType1>()
    .Left.JoinAlias(productListType1 => productListType1.Details, () => detailAlias)
    .Left.JoinAlias(() => detailAlias.Product, () => productAlias)
    .Where(productListType1 => productListType1.Next == "abc" || productListType1.Final == "abc")
    .And(productListType1 => productListType1.Status.IsIn(new string[] { "STATUS1", "STATUS2", "STATUS3", "STATUS4"}))
    .WithSubquery.WhereNotExists(QueryOver.Of<ProductListType2.Detail>(() => productListType2DetailAlias)
        .Select(productListType2Detail => productListType2Detail.Product.id)
        .Inner.JoinAlias(productListType2Detail => productListType2Detail.ProductListType2, () => productListType2Alias)
        .Where(productListType2Detail => productListType2Detail.SequenceNumber < 900)
        .And(productListType2Detail => productListType2Detail.Product.Id == detailAlias.Product.Id)
        .And(() => productListType2Alias.Date == DateTime.Today)
        .And(() => productListType2Alias.Category == "D")
    )
    .TransformUsing(Transformers.DistinctRootEntity)
    .List();

Генерируемый sql при вызове выглядит следующим образом.

SELECT (lots of stuff)
FROM PRODUCT_LIST_TYPE1_TABLE this_
LEFT OUTER JOIN PRODUCT_LIST_TYPE1_DETAILS_TABLE detailalia1_
    ON this_.id=detailalia1_.parentId
LEFT OUTER JOIN PRODUCT_TABLE product2_
    ON detailalia1_.productId=product2_.id
WHERE (this_.next = ? or this_.dest = ?)
AND this_.stat in (?, ?, ?, ?)
AND NOT EXISTS (
    SELECT this_0_.productId as y0_
    FROM PRODUCT_LIST_TYPE2_DETAILS_TABLE this_0_
    WHERE this_0_.sequenceNumber < ?
    AND this_0_.productId = detailalia1_.pron
    AND productlisttype2_.date = ?
    AND productlisttype2_.type = ?
); PARAMETERS

Сгенерированный sql вызывает исключение:

GenericADOException: {"SQL5001 Column qualifier or table productlisttype2_ undefined."}

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

Чтобы было ясно, sql, который я ищу для его создания, это:

SELECT (lots of stuff)
FROM PRODUCT_LIST_TYPE1_TABLE this_
LEFT OUTER JOIN PRODUCT_LIST_TYPE1_DETAILS_TABLE detailalia1_
    ON this_.id=detailalia1_.parentId
LEFT OUTER JOIN PRODUCT_TABLE product2_
    ON detailalia1_.productId=product2_.id
WHERE (this_.next = ? or this_.dest = ?)
AND this_.stat in (?, ?, ?, ?)
AND NOT EXISTS (
    SELECT this_0_.productId as y0_
    FROM PRODUCT_LIST_TYPE2_DETAILS_TABLE this_0_
    INNER JOIN PRODUCT_LIST_TYPE2_TABLE productlisttype2_  // THIS PART IS MISSING
        ON this_0_.parentId=productlisttype2_.id
        AND productlisttype2_.date = ?
        AND productlisttype2_.type = ?
    WHERE this_0_.sequenceNumber < ?
    AND this_0_.productId = detailalia1_.pron
); PARAMETERS

или примерно эквивалентно внутри подзапроса.

Обновление: я также попытался изменить:

 .Inner.JoinAlias(productListType2Detail => productListType2Detail.ProductListType2, () => productListType2Alias)

to

 .Inner.JoinAlias(() => productListType2DetailAlias.ProductListType2, () => productListType2Alias)

и попытался использовать запрос на соединение:

 .Inner.JoinQueryOver(productListType2Detail => productListType2DetailAlias.ProductListType2)

оба изменения генерируют один и тот же sql, где INNER JOIN отсутствует.


person Ryan Thomas    schedule 06.10.2012    source источник


Ответы (1)


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

ProductListType1.Detail detailAlias = null;
Product productAlias = null;

ProductListType2 productListType2Alias = null;
ProductListType2.Detail productListType2DetailAlias = null;

_session.QueryOver<ProductListType1>()
    .Left.JoinAlias(productListType1 => productListType1.Details, () => detailAlias)
    .Left.JoinAlias(() => detailAlias.Product, () => productAlias)
    .Where(productListType1 => productListType1.Next == "abc" || productListType1.Final == "abc")
    .And(productListType1 => productListType1.Status.IsIn(new string[] { "STATUS1", "STATUS2", "STATUS3", "STATUS4"}))
    .WithSubquery.WhereNotExists(QueryOver.Of<ProductListType2.Detail>(() => productListType2DetailAlias)
        .Select(productListType2Detail => productListType2Detail.Product.id)
        .Inner.JoinAlias(() => productListType2Detail.ProductListType2, () => productListType2Alias)
        .Where(productListType2Detail => productListType2Detail.SequenceNumber < 900)
        .And(productListType2Detail => productListType2Detail.Product.Id == detailAlias.Product.Id)
        .And(() => productListType2Alias.Date == DateTime.Today)
        .And(() => productListType2.Category == "D")
    )
    .TransformUsing(Transformers.DistinctRootEntity)
    .List();

Изменение,

.Inner.JoinAlias(productListType2Detail => productListType2Detail.ProductListType2, () => productListType2Alias)

to

.Inner.JoinAlias(() => productListType2Detail.ProductListType2, () => productListType2Alias)
person Low Flying Pelican    schedule 08.10.2012
comment
Я попытался внести предложенные вами изменения, но изменение на () => productListType2Detail.ProductLIstType2 даже не скомпилировалось. Он говорит, что имя productListType2Detail не существует в текущем контексте. Я попытался изменить ссылки для .Inner.Join, чтобы использовать псевдоним, созданный при вызове QueryOver.Of (т.е. .Inner.JoinAlias(() => productListType2DetailAlias.ProductListType2, () => productListType2Alias). Это скомпилирует однако он генерирует тот же sql, что и предыдущая версия кода, но по-прежнему отсутствует внутреннее соединение. - person Ryan Thomas; 08.10.2012