2012-08-14 13 views
5

Estoy intentando unirme a varias entidades mediante JoinAlias, y no puedo encontrar la manera de obtener más de una de ellas para unirme. El código siguiente produce un error de SQL:NHibernate QueryOver alias de unión múltiple, solo el primero genera una unión

[TestMethod] 
public void TestAliases() 
{ 
    App_Start.NHibernateProfilerBootstrapper.PreStart(); 

    var type = new ShirtStyleType {Id = 1}; 
    var style = new ShirtStyle {Id = 1, ShirtStyleType = type}; 
    var shirt = new Shirt {Id = 1}; 
    var shirtStyle = new ShirtShirtStyle {Shirt = shirt, ShirtStyle = style}; 
    shirt.ShirtStyles = new[] {shirtStyle}; 

    using (Session.BeginTransaction()) 
     Session.Save(shirt); 

    Session.Clear(); 

    using (Session.BeginTransaction()) 
    { 
     Shirt shirtAlias = null; 
     ShirtShirtStyle shirtStylesAlias = null; 
     ShirtStyle shirtStyleAlias = null; 
     ShirtStyleType shirtStyleTypeAlias = null; 

     var query = Session.QueryOver<Shirt>(() => shirtAlias) 
      .JoinAlias(() => shirtAlias.ShirtStyles,() => shirtStylesAlias) 
      .JoinAlias(() => shirtStylesAlias.ShirtStyle,() => shirtStyleAlias) 
      .JoinAlias(() => shirtStyleAlias.ShirtStyleType,() => shirtStyleTypeAlias) 
      .Where(() => shirtStyleTypeAlias.Id == 1) 
      .List(); 
    } 
} 

El error:

ERROR: 
SQLite error 
no such column: shirtstyle3_.Id 

El SQL que provoca el error:

SELECT this_.Id    as Id0_1_, 
     shirtstyle1_.Shirt  as Shirt1_0_, 
     shirtstyle1_.ShirtStyle as ShirtStyle1_0_ 
FROM "Shirt" this_ 
     inner join "ShirtShirtStyle" shirtstyle1_ 
     on this_.Id = shirtstyle1_.Shirt_id 
WHERE shirtstyle3_.Id = 1 /* @p0 */ 

Es muy obvio para ver por qué el error está ocurriendo - Falta la combinación de combinaciones, específicamente cada combinación que no sea 'ShirtShirtStyle'. Desde mi comprensión de JoinAlias, el código que proporcioné debe estar uniendo a las tablas necesarias, pero no lo está y no entiendo por qué. ¿Hay algo más que necesito para que JoinAlias ​​funcione en este caso?

Las entidades y asignaciones que creé para esta prueba están debajo, en caso de que tenga algo que ver con la forma en que se asignan.

Entidades:

public class Shirt 
{ 
    public virtual int Id { get; set; } 
    public virtual IList<ShirtShirtStyle> ShirtStyles { get; set; } 
} 

public class ShirtShirtStyle 
{ 
    public virtual Shirt Shirt { get; set; } 
    public virtual ShirtStyle ShirtStyle { get; set; } 

    protected bool Equals(ShirtShirtStyle other) 
    { 
     return Equals(Shirt, other.Shirt) && Equals(ShirtStyle, other.ShirtStyle); 
    } 

    public override bool Equals(object obj) 
    { 
     if (ReferenceEquals(null, obj)) return false; 
     if (ReferenceEquals(this, obj)) return true; 
     if (obj.GetType() != this.GetType()) return false; 
     return Equals((ShirtShirtStyle) obj); 
    } 

    public override int GetHashCode() 
    { 
     unchecked 
     { 
      return ((Shirt != null ? Shirt.GetHashCode() : 0)*397)^(ShirtStyle != null ? ShirtStyle.GetHashCode() : 0); 
     } 
    } 
    } 

    public class ShirtStyle 
    { 
     public virtual int Id { get; set; } 
     public virtual ShirtStyleType ShirtStyleType { get; set; } 
    } 

    public class ShirtStyleType 
    { 
     public virtual int Id { get; set; } 
    } 

Maps:

public class ShirtMap : ClassMap<Shirt> 
{ 
    public ShirtMap() 
    { 
     Id(x => x.Id).GeneratedBy.Assigned(); 
     HasMany(x => x.ShirtStyles); 
    } 
} 

public sealed class ShirtShirtStyleMap : ClassMap<ShirtShirtStyle> 
{ 
    public ShirtShirtStyleMap() 
    { 
     CompositeId() 
      .KeyReference(x => x.Shirt) 
      .KeyReference(x => x.ShirtStyle); 
    } 
} 

public sealed class ShirtStyleMap : ClassMap<ShirtStyle> 
{ 
    public ShirtStyleMap() 
    { 
     Id(x => x.Id).GeneratedBy.Assigned(); 
     References(x => x.ShirtStyleType); 
    } 
} 

public sealed class ShirtStyleTypeMap : ClassMap<ShirtStyleType> 
{ 
    public ShirtStyleTypeMap() 
    { 
     Id(x => x.Id).GeneratedBy.Assigned(); 
    } 
} 
+0

Supongo que debería usar JoinQueryOver en lugar de JoinAlias. –

Respuesta

2

bien esta consulta parece funcionar como se espera - el problema parece ser con Fluido NHibernate. Aunque las referencias se especifican en una entidad compuesta mediante .KeyReference, necesita explícitamente volver a especificarlas en la asignación, por https://stackoverflow.com/a/10995486/981205. No estoy seguro si esto es un error o comportamiento esperado.

+0

Gracias por esto, pensé que me estaba volviendo loco. Lo molesto es que el problema solo ocurre si estás utilizando query over, si usas linq, nhibernate crea las combinaciones. El problema es que necesito uniones externas, por lo tanto, tengo que usar la consulta más ... – setebos