NHibernate连接和投影属性

时间:2010-05-26 23:10:45

标签: c# nhibernate linq-to-nhibernate

我有简单的情况(比如图像link text)和简单的SQL查询

SELECT  M.Name, 
          A.Name, 
          B.Name 
FROM Master M       LEFT JOIN DetailA A
ON M.DescA = A.Id   LEFT JOIN DetailB B
ON M.DescB = B.Id

如何使用CriteriaAPI在nHibernate中获得相同的效果?

我有这样的事情:

public class Employee : ClassBase, IContactData
{
    public virtual string FirstName { get; set; }
    public virtual string MiddleName { get; set; }
    public virtual string LastName { get; set; }
    public virtual string NickName { get; set; }
    public virtual string Login { get; set; }
    public virtual string Password { get; set; }
    public virtual string ContactPerson { get; set; }
    public virtual string PESEL { get; set; }
    public virtual string IdentificationNo { get; set; }
    public virtual string NIP { get; set; }
    public virtual string Description { get; set; }
    public virtual string Profession { get; set; }
    public virtual byte[] Photo { get; set; }
    public virtual DateTime? BirthDate { get; set; }
    public virtual Boolean SpecialUser { get; set; }
    public virtual Boolean Sex { get; set; }
    public virtual Item Gender { get; set; }
    public virtual Item Position { get; set; }
    public virtual Item Status { get; set; }
    public virtual Item Nation { get; set; }
    public virtual Item Education { get; set; }
    public virtual Item JobType { get; set; }
    public virtual ISet<Address> Addresses { get; set; }
}

public class Item : ClassBase
{

    public virtual int ItemCode { get; set; }
    public virtual int DictCode{ get; set;}
    public virtual string Description{ get; set;}

    public override string ToString()
    {
        return Description;
    }
}

public class Address : ClassBase
{
    public virtual string Description { get; set; }
    public virtual string District { get; set; }
    public virtual string Community { get; set; }
    public virtual string City { get; set; }
    public virtual string Street { get; set; }
    public virtual string PostalCode { get; set; }
    public virtual string HouseNo { get; set; }
    public virtual string FlatNo { get; set; }
    public virtual Boolean Official { get; set; }
    public virtual Item Country { get; set; }
    public virtual Item Region { get; set; }
}

映射:

                        

<property name="FirstName"        column="FIRST_NAME"         type="string"   length="50"    not-null="true"/>
<property name="MiddleName"       column="MIDDLE_NAME"        type="string"   length="50"    not-null="false"/>
<property name="LastName"         column="LAST_NAME"          type="string"   length="50"    not-null="true"/>
<property name="NickName"         column="NICKNAME"           type="string"   length="50"    not-null="false"/>
<property name="Login"            column="LOGIN"              type="string"   length="30"    not-null="false"/>
<property name="Password"         column="PASSWORD"           type="string"   length="100"   not-null="false"/>
<property name="ContactPerson"    column="CONTACT_PERSON"     type="string"   length="250"   not-null="false"/>
<property name="PESEL"            column="PESEL"              type="string"   length="11"    not-null="false"/>
<property name="IdentificationNo" column="IDENTIFICATION_NO"  type="string"   length="12"    not-null="false"/>
<property name="NIP"              column="NIP"                type="string"   length="11"    not-null="false"/>
<property name="Description"      column="DESCRIPTION"        type="string"   length="1000"  not-null="false"/>
<property name="Profession"       column="PROFESSION"         type="string"   length="150"   not-null="false"/>
<property name="BirthDate"        column="BIRTH_DATE"         type="DateTime"                not-null="false"/>
<property name="Photo"            column="PHOTO"              type="BinaryBlob"              not-null="false"/>
<property name="Sex"              column="SEX"                type="Boolean"                 not-null="false"/>
<property name="SpecialUser"      column="SPECIAL_USER"       type="Boolean"                 not-null="false"/>

<many-to-one name="Gender"        column="DIC_GENDER"         not-null="false" class="DomainModel.ERP.Item,DomainModel" />
<many-to-one name="Position"      column="DIC_POSITION"       not-null="false" class="DomainModel.ERP.Item,DomainModel" />
<many-to-one name="Status"        column="DIC_STATUS"         not-null="false" class="DomainModel.ERP.Item,DomainModel" />
<many-to-one name="Nation"        column="DIC_NATION"         not-null="false" class="DomainModel.ERP.Item,DomainModel" />
<many-to-one name="Education"     column="DIC_EDUCATION"      not-null="false" class="DomainModel.ERP.Item,DomainModel" />
<many-to-one name="JobType"       column="DIC_JOB_TYPE"       not-null="false" class="DomainModel.ERP.Item,DomainModel" />

<set name="Addresses" table="TBL_ADDRESS" generic="true">
  <key column="FK_EMPLOYEE" />
  <one-to-many class="DomainModel.ERP.HRM.Address,DomainModel"/>
</set>

                        

<property name="ItemCode"         column="ITEM_CODE"          type="integer"  not-null="true"/>
<property name="DictCode"         column="TABLE_CODE"         type="integer"  not-null="true"/>
<property name="Description"      column="NAME"               type="string"   length="200"   not-null="true"/>

                   

<version  name="Version"      column="VERSION"       type="integer"  unsaved-value="0"/>
<property name="Description"  column="DESCRIPTION"   type="string"   length="1000"  not-null="false"/>
<property name="District"     column="DISTRICT"      type="string"   length="15"    not-null="false"/>
<property name="Community"    column="COMMUNITY"     type="string"   length="150"   not-null="false"/>
<property name="City"         column="CITY"          type="string"   length="150"   not-null="true"/>
<property name="Street"       column="STREET"        type="string"   length="150"   not-null="true"/>
<property name="PostalCode"   column="POSTAL_CODE"   type="string"   length="10"    not-null="false"/>
<property name="HouseNo"      column="HOUSENO"       type="string"   length="20"    not-null="true"/>
<property name="FlatNo"       column="FLATNO"        type="string"   length="20"    not-null="false"/>
<property name="Official"     column="IS_OFFICIAL"   type="Boolean"                 not-null="true"/>

<many-to-one name="Country"           column="DIC_COUNTRY"      not-null="false"  class="DomainModel.ERP.Item,DomainModel" />
<many-to-one name="Region"            column="DIC_REGION"       not-null="false"  class="DomainModel.ERP.Item,DomainModel" />

我需要:

  1. 将数据传输到我的网格控件
    • - FirstName,
      - LastName,
      - NIP,
      - Position.Description,
      - Education.Description,
      - JobType.Description,
      - Country.Description - 来自Address.Official为真的地址,
      - 街道 - 来自Address.Official为真的地址,
      - HouseNo - 来自Address.Official为真的地址,
      - FlatNo - 来自Address.Official为真的地址。
    1. 将数据传输到另一个网格Control
      • - FirstName,
        - LastName,
        - NIP,
        - Position.Description,
        - Education.Description,
        - JobType.Description。

      并且最重要的是思考。我想只使用一个SELECT语句来做这个。 现在,对于第1点,我使用NamedSQLQuery并且一切正在工作,但对于最简单的情况,我想使用CriteriaAPI。

      对于第1点和第2点,我有DTO类,我将查询结果转换为此类。

      我可以通过GetAllEmployees()执行此操作,但许多属性是Lazy Loaded并且这样做我在应用程序和数据库之间有一个巨大的流量。我可以将这些属性更改为Eager Loading,但在我看来,有太多的数据要回溯,我不需要。

2 个答案:

答案 0 :(得分:7)

我找到了解决办法:)

var master = DetachedCriteria.For<Master>()
        .CreateAlias("DetailA", "detA", JoinType.LeftOuterJoin)
        .CreateAlias("DetailB", "detB", JoinType.LeftOuterJoin)
        .SetProjection
        (
            Projections.ProjectionList()
            .Add(Projections.Property("Id"), "Id")
            .Add(Projections.Property("Name"), "MasterName")
            .Add(Projections.Property("detA.Name"), "DetailAName")
            .Add(Projections.Property("detB.Name"), "DetailBName")
        )
        .SetResultTransformer(Transformers.AliasToBean(typeof (MasterDTO)));

class MasterDTO
{
    public virtual int Id {get;set;}
    public virtual string MasterName {get;set;}
    public virtual string DetailAName {get;set;}
    public virtual string DetailBName {get;set;}

    public MasterDTO()
    {}

    public MasterDTO(int id, string mastername, string detailaname, string detailbname)
    {
        Id = id;
        MasterName = mastername;
        DetailAName = detailaname;
        DetailBName = detailbname;
    }
}

答案 1 :(得分:5)

我对这种情况的建议 - 你想要显示一个包含来自多个实体的数据的网格,只需创建一个sql视图并用NH映射它。

从长远来看,你会更幸福