2010-06-09 2 views
5

У меня есть следующие объекты, определенные в моей Entity Model:HQL запрос через подклассы

public class MyContainer 
{ 
    public virtual ICollection<Base> Subs { get; set; } 
} 

public abstract class Base 
{ 
    public virtual Guid Id { get; set; } 
} 
public abstract class Sub1 : Base 
{ 
    public virtual int MyValue { get; set; } 
} 
public abstract class Sub2 : Base 
{ 
    public virtual int MyValue { get; set; } 
} 

и следующее FluentNHibernate отображение для вышеуказанных лиц:

public sealed class BaseMap : ClassMap<Base> 
{ 
    public BaseMap() 
    { 
     Table("BaseTable"); 
     Id(e => e.Id); 
    } 
} 

public sealed class Sub1Map : SubClassMap<Sub1> 
{ 
    public Sub1Map() 
    { 
     Table("Sub1Table"); 
     KeyColumn("BaseId"); 

     Map(e => e.Myvalue); 
    } 
} 

public sealed class Sub2Map : SubClassMap<Sub2> 
{ 
    public Sub2Map() 
    { 
     Table("Sub2Table"); 
     KeyColumn("BaseId"); 

     Map(e => e.Myvalue); 
    } 
} 

Когда я запускаю следующий HQL :

select sub 
    from MyContainer container 
     join fetch container.Subs sub 
    where sub.MyValue = :p1 

Генерируемый SQL применяет только ограничение в предложении WHERE для одного из подклассов ho Веверу, генерируемый соединения являются правильными, то есть, следующий скелетной SQL генерируется:

SELECT ... 
FROM BaseTable bt 
    INNER JOIN Sub1Table st1 ON ... 
    INNER JOIN Sub2Table st2 ON ... 
WHERE st1.MyValue = @p1 

, где, как я ожидал дополнительный OR в ИНЕКЕ:

SELECT ... 
FROM BaseTable bt 
    INNER JOIN Sub1Table st1 ON ... 
    INNER JOIN Sub2Table st2 ON ... 
WHERE st1.MyValue = @p1 
     OR st2.MyValue = @p2 

Есть ли что-то я m отсутствует или есть способ переписать HQL, чтобы я мог ссылаться на каждый подкласс в предложении WHERE и применять ограничение напрямую (предполагая, что он будет генерировать дополнительное ограничение в сгенерированном SQL)?

Я использую NHibernate 3.0.0.

+0

Если Я использую устаревший метод JoinSubClass() вместо создания сопоставлений с использованием SubclassMap, который изменяет порядок ограничения в выражении WHERE. Я не понимаю ... это должно работать, не так ли? –

ответ

1

MyValue должен быть объявлен и нанесен на карту в Base. Это не возможно фильтровать базовый класс свойствами, которые определены в подклассах без приведения к конкретному классу:

where (b.class = Sub1 and b.MyValue = :p1) or (b.class = Sub2 and b.MyValue = :p1) 

EDIT: Или в FNH1.2 накидной подклассов можно использовать:

public class BaseMap : ClassMap<Base> 
{ 
    public BaseMap() 
    { 
     UseUnionSubclassForInheritanceMapping(); 
     Table("BaseTable"); 
     Id(e => e.Id); 
    } 
} 
Смежные вопросы