我試圖連接使用JoinAlias的幾個實體,並且無法弄清楚如何獲取多個連接。下面的代碼導致SQL錯誤:NHibernate QueryOver多重連接別名,只有第一個生成連接
[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();
}
}
錯誤:
ERROR:
SQLite error
no such column: shirtstyle3_.Id
導致錯誤的SQL:
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 */
這是非常明顯的看出爲什麼錯誤發生 - 查詢缺少連接,特別是除「ShirtShirtStyle」之外的每個連接。從我對JoinAlias的理解,我提供的代碼應該加入必要的表格,但它不是,我不明白爲什麼。在這種情況下,有什麼需要讓JoinAlias工作?
我爲這個測試創建的實體和映射如下,以防它們與它們的映射方式有關。
實體:
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; }
}
地圖:
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();
}
}
我的猜測是你應該使用JoinQueryOver代替JoinAlias。 – 2012-08-14 22:49:08