2010-06-09 25 views
5

tôi có các đối tượng sau được định nghĩa trong Entity Mẫu của tôi:HQL truy vấn trên tiểu lớp

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

và ánh xạ FluentNHibernate sau cho các đối tượng trên:

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

Khi tôi chạy HQL sau :

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

SQL được tạo chỉ áp dụng ràng buộc trong mệnh đề WHERE cho một trong các lớp con, ho wever, được tạo ra tham gia được đúng, nghĩa là SQL xương sau đây được tạo:

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

nơi như tôi mong đợi thêm HOẶC trong mệnh đề WHERE:

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

Có một cái gì đó tôi m thiếu, hoặc là có một cách để viết lại HQL để tôi có thể tham khảo mỗi lớp con trong mệnh đề WHERE và áp dụng ràng buộc trực tiếp (giả sử rằng nó sẽ tạo ra ràng buộc bổ sung trong SQL được sinh ra)?

Tôi đang sử dụng NHibernate 3.0.0.

+0

Nếu Tôi sử dụng phương thức JoinSubClass() lỗi thời thay vì tạo ánh xạ bằng cách sử dụng SubclassMap, nó thay đổi thứ tự của ràng buộc nào xuất hiện trong mệnh đề WHERE. Tôi không hiểu ... điều này nên làm việc phải không? –

Trả lời

1

MyValue phải được khai báo và ánh xạ trong Cơ sở. Không thể để lọc lớp cơ sở bằng tài sản mà được định nghĩa trong lớp con mà không cần đúc vào lớp học đặc biệt:

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

EDIT: Hoặc trong FNH1.2 đoàn subclassing thể được sử dụng:

public class BaseMap : ClassMap<Base> 
{ 
    public BaseMap() 
    { 
     UseUnionSubclassForInheritanceMapping(); 
     Table("BaseTable"); 
     Id(e => e.Id); 
    } 
} 
Các vấn đề liên quan