NHibernate投影组件

时间:2010-06-14 05:00:05

标签: nhibernate

大家好我试图用NHibernate中的投影来水化DTO这是我的代码

IList<PatientListViewModel> list = 
                                    y.CreateCriteria<Patient>()                                 
                                            .SetProjection(Projections.ProjectionList()
                                            .Add(Projections.Property("Birthdate"), "Birthdate")
                                            .Add(Projections.Property("Doctor.Id"), "DoctorId")
                                            .Add(Projections.Property("Gender"), "Gender")
                                            .Add(Projections.Property("Id"), "PatientId")
                                            .Add(Projections.Property("Patient.Name.Fullname"), "Fullname")     
                               )
                         .SetResultTransformer(Transformers.AliasToBean<PatientListViewModel>())
                         .List<PatientListViewModel>();  

此代码抛出异常?有谁知道这是什么问题?

这是错误消息

Message: could not resolve property: Patient.Name.Fullname of: OneCare.Domain.Entities.Patient

1 个答案:

答案 0 :(得分:2)

您必须为Parent.Name属性创建连接。

在尝试设置投影以创建Patient.Name属性的别名之前,请先尝试

如参见

IList<PatientListViewModel> list = 
                                y.CreateCriteria<Patient>()
                                 .CreateAlias("Name", "name")

                                        .SetProjection(Projections.ProjectionList()
                                        .Add(Projections.Property("Birthdate"), "Birthdate")
                                        .Add(Projections.Property("Doctor.Id"), "DoctorId")
                                        .Add(Projections.Property("Gender"), "Gender")
                                        .Add(Projections.Property("Id"), "PatientId")
                                        .Add(Projections.Property("name.Fullname"), "Fullname")     
                           )

对不起,我没有检查这个,因为所有都取决于您的实体类。但这个想法是你必须创建一个别名。 如果您无法解决问题,请提供您的课程。

已更新!

我创建了两个实体,患者和医生:

 public class Patient : AdvanceEntity
{
    public virtual DateTime BirthDate { get; set; }

    public virtual Doctor Doctor { get; set; }

    public virtual int Gender { get; set; }

    public virtual string Name { get; set; }
}

public class Doctor : AdvanceEntity
{
    public virtual string Name { get; set; }
}

接下来,存储库仅包含转换为Criteria API的您的查询

public IList<Patient> GetPatientsForDoctor(long doctorId)
    {
        return this.Session.CreateCriteria(typeof(Patient), "patient")
            .CreateAlias("patient.Doctor", "doc")
            .Add(Restrictions.Eq("doc.Id", doctorId))
            .List<Patient>()
        ;
    }

这是单元测试和查询结果

    [Test]
    public void CanGetPatients()
    {
        var repository = new PatientRepository();
        repository.GetPatientsForDoctor(1L);
    }

结果是:

 NHibernate: SELECT this_.patientId as patientId70_1_, this_.birthDate as birthDate70_1_, this_.gender as gender70_1_, 
this_.name as name70_1_, this_.deletedDate as deletedD5_70_1_, this_.doctorId as doctorId70_1_, 
this_.deletedById as deletedB7_70_1_, doc1_.doctorId as doctorId71_0_, doc1_.name as name71_0_, 
doc1_.deletedDate as deletedD3_71_0_, doc1_.deletedById as deletedB4_71_0_ 
FROM Patients this_ 
inner join Doctors doc1_ on this_.doctorId=doc1_.doctorId 
WHERE doc1_.doctorId = @p0;@p0 = 1

正如我所说,你只需创建一个Alias并在它们之间连接表。 但我认为,在这种情况下使用HQL更合理。只有使用动态查询才能使用条件。如您所见,标准选择所有可能导致性能不足的字段。当然,你正在处理简单的事情,但在实际应用中要非常谨慎地使用生成的查询。

度过美好的一天!