2010-02-23 60 views
1

这些都是我的实体(简化):NHibernate的查询问题

public class IdentificationRequest 
{ 
    private int id; 
     private ICollection<IdentificationRequestStateHistoryItem> stateHistoryItems; 

     public virtual string Id 
     { 
      get { return id; } 
      private set { id = value; } 
     }     

     public virtual IEnumerable<IdentificationRequestStateHistoryItem> StateHistoryItems 
     { 
      get { return stateHistoryItems; } 
      private set { stateHistoryItems = new List<IdentificationRequestStateHistoryItem>(value); } 
     } 

     public void ChangeState(IdentificationRequestState state) 
     { 
     // state transition here 
      var stateHistoryItem = new IdentificationRequestStateHistoryItem(state, this); 
      stateHistoryItems.Add(stateHistoryItem); 
     }  
} 


public class IdentificationRequestStateHistoryItem 
{ 
    private int id; 
     private IdentificationRequestState state; 
     private EntityTimestamp timestamp; 

     public virtual string Id 
     { 
      get { return id; } 
      private set { id = value; } 
     }     

    public virtual IdentificationRequestState State 
    { 
     get { return state; } 
     private set { state = value; } 
    } 

    public virtual EntityTimestamp Timestamp 
    { 
     get { return timestamp; } 
     private set { timestamp = value; } 
     } 
} 



public class IdentificationRequestState 
{ 
    // possible states are 
    // Received, then id = 10 
    // Finished, then id = 20 
    private int id; 

    private string name; 

     public virtual string Name 
     { 
      get { return name; } 
      private set { name = value; } 
     } 

     public virtual string Id 
     { 
      get { return id; } 
      private set { id = value; } 
     }   
} 

public class EntityTimestamp 
    { 
     private DateTime createdOn; 


     public virtual DateTime CreatedOn 
     { 
      get { return createdOn; } 
      private set { createdOn = value; } 
     } 

     private IUser createdBy; 


     public virtual IUser CreatedBy 
     { 
      get { return createdBy; } 
      private set { createdBy = value; } 
     } 

     private DateTime changedOn; 


     public virtual DateTime ChangedOn 
     { 
      get { return changedOn; } 
      private set { changedOn = value; } 
     } 

     private IUser changedBy; 


     public virtual IUser ChangedBy 
     { 
      get { return changedBy; } 
      private set { changedBy = value; } 
     } 
}   

所以上面读起来就像下面并设计一样,在数据库中。

一个IdentificationRequest可以跟踪其IdentificationRequestState转换。因此,每次分配新的IdentificationRequestState时,都会创建一个新的IdentificationRequestStateHistoryItem,并将其放入多个历史记录项目的集合中。这意味着,当前IdentificationRequestState是最后一个添加的(由createdOn日期表示)。

所以,现在我的问题是,查询的样子,列出所有IdentificationRequest的whos当前状态是收到,或完成。

这是我走到这一步:

private ICollection<IdentificationRequest> GetByCurrentState(IdentificationRequestState state) 
{ 
    var session = GetCurrentSession(); 

    var subCriteria = DetachedCriteria.For(typeof(IdentificationRequestStateHistoryItem))    
     .SetProjection(Projections.Property("identificationRequest.Id")); 

    subCriteria.Add(Restrictions.Eq("State", state)); 

    var criteria = session 
     .CreateCriteria(typeof (IdentificationRequest)) 
     .Add(Subqueries.PropertyIn("Id", subCriteria)) 
     .SetResultTransformer(new NHibernate.Transform.DistinctRootEntityResultTransformer()); 

    return criteria.List<IdentificationRequest>();   
} 

但是使用这个查询时,并寻求其当前状态标识请求收到时,我也得请求以来的要求有其当前的状态下结束之前收到的状态。所以我需要用Max(CreatedOn)做些什么...?

NHibernate的映射:

<class name="IdentificationRequest" table="IdentificationRequest"> 

    <id name="Id" column="IdentificationRequestId" unsaved-value="-1"> 
     <generator class="identity"/> 
    </id> 

    <bag name="stateHistoryItems" access="field" order-by="CreatedOn desc" fetch="join" cascade="all-delete-orphan" lazy="false"> 
     <key column="IdentificationRequestId"/> 
     <one-to-many class="IdentificationRequestStateHistoryItem"/> 
    </bag> 

    </class> 


    <class name="IdentificationRequestStateHistoryItem" table="IdentificationRequestStateHistoryItem"> 

     <id name="Id" column="IdentificationRequestStateHistoryItemId" unsaved-value="-1"> 
     <generator class="identity"/> 
     </id> 

     <many-to-one name="identificationRequest" access="field" lazy="false" cascade="none" column="IdentificationRequestId" class="IdentificationRequest"></many-to-one> 

     <many-to-one name="State" lazy="false" fetch="join" cascade="none" column="IdentificationRequestStateId" class="IdentificationRequestState"></many-to-one> 

     <component name="Timestamp" class="EntityTimestamp"> 
     <property name="CreatedOn"/> 
     <component name="CreatedBy" class="User"> 
      <property name="Name" column="CreatedBy" /> 
     </component> 
     <property name="ChangedOn"/> 
     <component name="ChangedBy" class="User"> 
      <property name="Name" column="ChangedBy" /> 
     </component> 
     </component> 

    </class> 


    <class name="IdentificationRequestState" table="IdentificationRequestState"> 

    <id name="Id" column="IdentificationRequestStateId" unsaved-value="-1"> 
     <generator class="assigned"/> 
    </id> 

    <property name="Name"/> 

    </class>  

回答

0

你会为自己节省很多痛苦由具有IdentificationRequest.CurrentState属性。

你对max()的想法是正确的。您可以在获取该请求的所有请求状态的最大(日期)的位置添加另一个子标准,然后为现有的子标准添加限制,使其date =最大日期。格罗斯,但这是我能想到的唯一方法。