2012-08-14 38 views
5

Tôi đang cố gắng tham gia trên một số thực thể bằng cách sử dụng JoinAlias ​​và không thể tìm ra cách để có được nhiều hơn một trong số họ tham gia. Kết quả mã sau vào một lỗi SQL:NHibernate QueryOver nhiều bí danh tham gia, chỉ lần đầu tiên tạo ra một tham gia

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

Lỗi:

ERROR: 
SQLite error 
no such column: shirtstyle3_.Id 

các SQL gây ra lỗi:

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 */ 

Nó rất rõ ràng cho thấy tại sao lỗi này là xảy ra - truy vấn thiếu tham gia, cụ thể là mỗi lần tham gia khác với 'ShirtShirtStyle'. Từ sự hiểu biết của tôi về JoinAlias, mã tôi đã cung cấp nên sẽ tham gia các bảng cần thiết, nhưng không phải vậy và tôi không hiểu tại sao. Có điều gì tôi cần phải làm cho JoinAlias ​​hoạt động trong trường hợp này?

Các thực thể và ánh xạ mà tôi đã tạo cho thử nghiệm này là dưới đây, trong trường hợp nó có liên quan đến cách chúng được ánh xạ.

Đối tượng:

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

Đoán của tôi là bạn nên sử dụng JoinQueryOver thay vì JoinAlias. –

Trả lời

2

Vâng truy vấn này dường như chức năng giống như mong đợi - vấn đề có vẻ là với thành thạo NHibernate. Mặc dù các tham chiếu được chỉ định trên đối tượng kết hợp qua .KeyReference, bạn cần phải rõ ràng chỉ định lại chúng trong ánh xạ, cho mỗi https://stackoverflow.com/a/10995486/981205. Không chắc chắn nếu đây là một lỗi hoặc hành vi dự kiến.

+0

Cảm ơn vì điều này, tôi nghĩ rằng tôi đã phát điên. Điều khó chịu là vấn đề chỉ xảy ra nếu bạn đang sử dụng truy vấn trên, nếu bạn sử dụng LINQ, nhibernate tạo các kết nối. Vấn đề là tôi cần kết nối bên ngoài, do đó tôi phải sử dụng truy vấn trên ... – setebos

Các vấn đề liên quan