c# - NHibernate查询问题

标签 c# java .net nhibernate hibernate

这些是我的实体(简化):

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 的当前状态为“已接收”或“已完成”。

这是我到目前为止得到的:

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>    

最佳答案

通过具有IdentificationRequest.CurrentState 属性,您可以省去很多麻烦。

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

关于c# - NHibernate查询问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2317668/

相关文章:

c# - 获取应用于通用方法的 PostSharp OnMethodBoundaryAspect 的通用参数

c# - 如何在我的项目中引用 TeamFoundation 程序集?

c# - 无法弄清楚为什么 GetFiles(...) 对我不起作用

java - 从数据库中获取特定列的最新行

.net - 检测到包降级警告(dotnet core,vs 2017)

c# - 如何在 WPF DataGrid 中按列搜索?

java - SwingWorker 创建多线程

java - Mybatis 3.0.5 插入/更新语句映射与多个输入

c# - 无法将类型 'DynamicClass1' 转换为类型 <T>。 LINQ to Entities 仅支持转换 EDM 原语或枚举类型

c# - "Beta: Use Unicode UTF-8 for worldwide language support"究竟做了什么?