NHibernate - TransformUsing.SingleOrDefault返回默认值

时间:2014-08-13 15:10:39

标签: c# nhibernate fluent-nhibernate


我有NHibernate的问题

我的映射:

<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,我不知道原因。 &#39; ^^(我登录了属性的setter,NHibernate也使用了它。) 如果我使用.SingleOrDefault()而不是(TransformUsing和SingleOrDefault),则值是我想要的值。那么,映射中是否有任何pb?

是否可以提供一些帮助? (顺便说一句,对不起,如果我犯了一些错误,英语不是我的主要语言^^)

1 个答案:

答案 0 :(得分:2)

我们在这里缺少的是.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>();