Проблема запроса NHibernate - PullRequest
       10

Проблема запроса NHibernate

1 голос
/ 23 февраля 2010

это мои сущности (упрощенно):

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 является последним добавленным (выраженным в дате создания).

Так что теперь мой вопрос в том, как будет выглядеть запрос, в котором перечислены все текущие состояния IdentificationRequest, полученные или завершенные.

Вот что я получил до сих пор:

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

Но при использовании этого запроса и при поиске идентификационного запроса с его текущим состоянием «Получено» я также получаю запросы с его текущим состоянием «Завершено», поскольку у запроса было состояние «Получено» ранее. Так что мне нужно что-то сделать с Максом (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>    

1 Ответ

0 голосов
/ 26 февраля 2010

Вы бы избавили себя от многих трудностей, обладая свойством IdentificationRequest.CurrentState.

Ваша мысль о max () верна. Вы можете добавить другой подкритерий, в котором вы берете максимальное (дата) всех запросов для этого запроса, а затем добавляете ограничение к существующим подкритериям, чтобы его дата = эта максимальная дата. Брутто, но это единственный способ, о котором я могу думать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...