2011-06-15 73 views
0

計數使用NHibernate 2.NHibernate的上映射的實體

在我們的系統,我們有存儲可能指向任何系統中的其他表,以及一些附加字段中記錄的表。例如

class PointerTable 
{ 
    public int ID; 
    public string ObjectName; 
    public int RecordID; 
    ... additional fields 
} 

ObjectName和的recordId域指向系統中的另一個表的名稱,並記錄在該表中,這個記錄指向ID。此表與系統中的其他表之間沒有關係。

當我從系統中的其他表中檢索記錄時,我需要能夠加入到這個表中,因爲我需要確定一個表是否在指向它的PointerTable中有任何記錄。即獲得該記錄的PointerTable中記錄的計數。

我試圖做到這一點在HQL:

select a.ID, e.Field1, a.Field2, a.Field3, 
      count(select * 
      from PointerTable p 
      where p.ObjectName = "Table1" 
       and p.RecordID = a.ID) 
from Table1 a 
where a.ParentTable.ID = :ID 

我也看着把一個映射到XML配置文件系統中的所有實體,將通過此表指出, 。所以我可以在每個其他實體中收集PointerTable記錄。雖然我不確定這是否可能。我找不到如何將映射設置爲映射到2個字段而不是主鍵。

喜歡的東西:

<bag name="PointerRecords" table="PointerTable" lazy="true" inverse="true">  
    <key> 
     <column name="ThisEntityID" /> 
     <column name="ObjectName" /> ?? Hard coded 
    </key> 
    <one-to-many class="PointerTable" not-found="ignore"/>  
</bag> 

這甚至可能嗎?

基本上我想要做的就是下面的SQL查詢。但理想情況下,我們希望通過HQL或映射完成此操作。這裏

SQL

select a.ID, e.Field1, a.Field2, a.Field3, Count(d.ID) 
from Table1 a 
inner join Table2 e on a.ParentID=e.ID 
left outer join PointerTable d on d.ObjectName = 'Table1' and d.RecordID = a.ID 
where c.ID = @ID 
group by a.ID, e.Field1, a.Field2, a.Field3 
+0

您的HQL似乎是爲了,除了不具有部分的 '按組'。什麼不工作?你是否得到例外?錯誤的結果? – 2011-06-15 18:33:10

+0

事實上,我得到一個NHibernate.QueryException異常「未定義的別名或未知的映射:d」 如果我刪除別名,生成的SQL是不正確的(... count_big(select * from PointerTable where ObjectName =「Table1」and RecordID = a.ID)as x1_0 _)...)而不是類似於SELECT(COUNT(*)FROM PointerTable WHERE ...),我得到一個SqlClient.SqlException異常。 – matt 2011-06-21 09:05:20

回答

1

的想法是將這個系列與where子句

使用fluentmapping映射:

public SomeEntityMap(){ 
    Table("SomeTable"); 

    HasMany(x => x.PointerRecords) 
     .Table("PointerTable") 
     .KeyColumn("ThisEntityID") 
     .Where("ObjectName = 'SomeTable'") 
} 

使用XML映射

開始編輯

<bag name="PointerRecords" table="PointerTable" lazy="true" inverse="true" where ="ObjectName = 'SomeTable'"> 
    <key column="ThisEntityID"/> 
    <one-to-many class="PointerTable" not-found="ignore"/> 
</bag> 

末編輯

和查詢一樣

object[] results = session.CreateCriteria<SomeEntity>() 
    .Add(Restrictions.Eq("Id", id)) 
    .SetProjection(Projections.ProjectionList() 
     .Add(Projections.Property("Field1")) 
     ... 
     .Add(Projections.Count("PointerRecords"))); 
    .List() 

var entities = session.CreateCriteria<SomeEntity>() 
    .Add(Restrictions.Eq("Id", id) 
    .SetFetchMode("PointerRecords", NHibernate.FetchMode.Eager) 
    .List<SomeEntity>(); 

entities[0].PointerRecords.Count 
+0

感謝您的回覆Firo,但我們不使用流利的nhibernate。 – matt 2011-06-21 08:47:16

+0

@matt我加了xml映射 – Firo 2011-06-21 10:10:15

+0

優秀!謝謝,很好地工作。 得到HQL現在與一個PointerRecords.size一起工作。 還添加了access =「none」屬性,因此我不必將集合添加到實體對象中(儘管我們現在可能希望添加它,現在可以使用此映射)。非常感謝。 – matt 2011-06-21 15:09:19