2010-06-09 15 views
5

tengo las siguientes entidades definidas en mi modelo de entidad:HQL consulta sobre subclases

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; } 
} 

y las siguientes asignaciones FluentNHibernate para las entidades anteriores:

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); 
    } 
} 

Cuando ejecuto el siguiente HQL :

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

SQL generado solo aplica una restricción en la cláusula WHERE para una de las subclases, ho Wever, generada combinaciones estén correcta, es decir, se genera el siguiente código SQL esquelético:

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

donde como estoy esperando un adicional de O en la cláusula WHERE:

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

¿Hay algo que' falta, o hay una manera de volver a escribir el HQL para que pueda hacer referencia a cada subclase en la cláusula WHERE y aplicar la restricción directamente (suponiendo que generaría la restricción adicional en el SQL generado)?

Estoy usando NHibernate 3.0.0.

+0

Si Utilizo el enfoque obsoleto JoinSubClass() en lugar de crear asignaciones usando SubclassMap, cambia el orden de la restricción que aparece en la cláusula WHERE. No entiendo ... esto debería funcionar, ¿no? –

Respuesta

1

MyValue debe declararse y correlacionarse en Base. No es posible filtrar clase base por las propiedades que se definen en las subclases sin poner a la clase particular:

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

EDIT: O en FNH1.2 subclases unión se pueden utilizar:

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