NHibernate - TransformUsing.SingleOrDefault返回默认值

本文关键字:返回 默认值 SingleOrDefault TransformUsing NHibernate | 更新日期: 2023-09-27 18:17:45


我使用NHibernate有一个问题

My mapping:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="StatsRow" table="StatsRow" lazy="true">
    <id name="StatsRowId" column="StatsRow_Id" type="int">
      <generator class="native" >
        <param name="sequence">SEQ_StatsRow</param>
      </generator>
    </id>
    <property name="JobId" column="JobId" type="string" not-null="true" />
    <property name="CreationTime" column="CreationTime" type="DateTime" not-null="true" />
    <property name="WorkflowName" column="WorkflowName" type="string" not-null="true"/>
    <property name="JobState" column="JobState" type="string" not-null="true" />
    <property name="LastErrorCode" column="LastErrorCode" type="string" not-null="true" />
    <property name="LastErrorMessage" column="LastErrorMessage" type="string" not-null="false" />
  </class>
</hibernate-mapping>

我的类StatsRow:

[Serializable]
internal class StatsRow
{
    protected int _statsrowid;
    protected string _jobid;
    protected DateTime _creationtime;
    protected string _workflowname;
    protected string _jobstate;
    protected string _lasterrorcode;
    protected string _lasterrormessage;
    public DocFactoryStatsRow() { }
    public virtual int StatsRowId
    {
        get { return _statsrowid; }
        set { _statsrowid = value; }
    }
    public virtual string JobId
    {
        get { return _jobid; }
        set { _jobid = value; }
    }
    public virtual DateTime CreationTime
    {
        get { return _creationtime; }
        set { _creationtime = value; }
    }
    public virtual string WorkflowName
    {
        get { return _workflowname; }
        set
        {
            if (value != null && value.Length > 200)
                throw new ArgumentOutOfRangeException("value", value.ToString(), "WorkflowName cannot contain more than 200 characters");
            _workflowname = value;
        }
    }
    public virtual string JobState
    {
        get { return _jobstate; }
        set
        {
            if (value != null && value.Length > 32)
                throw new ArgumentOutOfRangeException("value", value.ToString(), "JobState cannot contain more than 32 characters");
            _jobstate = value;
        }
    }
    public virtual string LastErrorCode
    {
        get { return _lasterrorcode; }
        set
        {
            if (value != null && value.Length > 64)
                throw new ArgumentOutOfRangeException("value", value.ToString(), "LastErrorCode cannot contain more than 64 characters");
            _lasterrorcode = value;
        }
    }
    public virtual string LastErrorMessage
    {
        get { return _lasterrormessage; }
        set
        {
            if (value != null && value.Length > 1073741823)
                throw new ArgumentOutOfRangeException("value", value.ToString(), "LastErrorMessage cannot contain more than 1073741823 characters");
            _lasterrormessage = value;
        }
    }
}

我想为给定的jobId的一个结果只检索几列(我没有显示所有列,太多^^),所以我使用:

var statRow = session.QueryOver<StatsRow>()
.Where(row => row.JobId == jobId)
.Select(
Projections.Property<StatsRow>(row => row.JobId),
Projections.Property<StatsRow>(row => row.JobState),
Projections.Property<StatsRow>(row => row.LastErrorCode),
Projections.Property<StatsRow>(row => row.LastErrorMessage),
Projections.Property<StatsRow>(row => row.CreationTime),
Projections.Property<StatsRow>(row => row.WorkflowName))
.TransformUsing(Transformers.AliasToBean<StatsRow>())
.SingleOrDefault<StatsRow>();

我检查了返回值是否正确,没有pb(生成的SQL查询也是正确的)。但是,这个代码片段返回一个具有默认值的StatsRow,我不知道为什么。^^(我登录了属性的setter, NHibernate也使用了它。)如果我使用。SingleOrDefault()而不是(TransformUsing和SingleOrDefault),则值就是我想要的。那么,映射中是否存在pb呢?

有可能有一点帮助吗?(顺便说一下,如果我犯了一些错误,很抱歉,英语不是我的主要语言^^)

NHibernate - TransformUsing.SingleOrDefault返回默认值

我们这里缺少的是.WithAlias()语句。那么,像这样的表达式:

Projections
   .Property<StatsRow>(row => row.JobId)
   .WithAlias(() => r.JobId),

将帮助Transformer决定哪个投影应该用于哪个属性:

StatsRow r = null;
var statRow = session.QueryOver<StatsRow>()
.Where(row => row.JobId == jobId)
.Select(
  Projections.Property<StatsRow>(row => row.JobId).WithAlias(() => r.JobId),
  Projections.Property<StatsRow>(row => row.JobState).WithAlias(() => r.JobState),
  ...
)
.Take(1)
.TransformUsing(Transformers.AliasToBean<StatsRow>())
.SingleOrDefault<StatsRow>();