select 如何仅加载根实体和所有带有标识符的内部实体(无状态会话)

How select only root entity and all inner entiry with identificator loaded(with statlesssession)

我的 hbm 配置:

    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-cascade="save-update" default-lazy="false">
  <class xmlns="urn:nhibernate-mapping-2.2" dynamic-insert="true" dynamic-update="true" optimistic-lock="version" name="LittleNHibernateProject.Model.CompanyBanan, LittleNHibernateProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="CompanyBanan">
    <cache region="CompanyBanan" usage="read-write" />
    <id name="Id" type="System.Int64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Id" />
      <generator class="increment" />
    </id>
    <version generated="always" name="VersionObject" type="System.Int64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" unsaved-value="0">
      <column name="VersionObject" not-null="true" default="1" />
    </version>
    <many-to-one class="LittleNHibernateProject.Model.FatherBanan, LittleNHibernateProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" foreign-key="FK_CompanyBanan_FatherBanan" name="FatherBanan">
      <column name="FatherBanan_id" />
    </many-to-one>
    <property name="Name" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Name" />
    </property>
  </class>
  <class xmlns="urn:nhibernate-mapping-2.2" dynamic-insert="true" dynamic-update="true" optimistic-lock="version" name="LittleNHibernateProject.Model.JobBanan, LittleNHibernateProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="JobBanan">
    <cache region="JobBanan" usage="read-write" />
    <id name="Id" type="System.Int64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Id" />
      <generator class="increment" />
    </id>
    <version generated="always" name="VersionObject" type="System.Int64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" unsaved-value="0">
      <column name="VersionObject" not-null="true" default="1" />
    </version>
    <any id-type="System.Int64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" meta-type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" name="Banan">
      <meta-value value="MotherBanan" class="LittleNHibernateProject.Model.MotherBanan, LittleNHibernateProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      <meta-value value="FatherBanan" class="LittleNHibernateProject.Model.FatherBanan, LittleNHibernateProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      <column name="Banan_Type" />
      <column name="Banan_Id" />
    </any>
    <property name="JobName" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="JobName" />
    </property>
  </class>
  <class xmlns="urn:nhibernate-mapping-2.2" dynamic-insert="true" dynamic-update="true" optimistic-lock="version" name="LittleNHibernateProject.Model.FatherBanan, LittleNHibernateProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="FatherBanan">
    <cache region="FatherBanan" usage="read-write" />
    <id name="Id" type="System.Int64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Id" />
      <generator class="increment" />
    </id>
    <version generated="always" name="VersionObject" type="System.Int64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" unsaved-value="0">
      <column name="VersionObject" not-null="true" default="1" />
    </version>
    <any id-type="System.Int64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" meta-type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" name="WifeBanan">
      <meta-value value="MotherBanan" class="LittleNHibernateProject.Model.MotherBanan, LittleNHibernateProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      <meta-value value="FatherBanan" class="LittleNHibernateProject.Model.FatherBanan, LittleNHibernateProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      <column name="Banan_Type" />
      <column name="Banan_Id" />
    </any>
    <property name="Name" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Name" />
    </property>
    <property name="Variety" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Variety" />
    </property>
  </class>
  <class xmlns="urn:nhibernate-mapping-2.2" dynamic-insert="true" dynamic-update="true" optimistic-lock="version" name="LittleNHibernateProject.Model.MotherBanan, LittleNHibernateProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="MotherBanan">
    <cache region="MotherBanan" usage="read-write" />
    <id name="Id" type="System.Int64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Id" />
      <generator class="increment" />
    </id>
    <version generated="always" name="VersionObject" type="System.Int64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" unsaved-value="0">
      <column name="VersionObject" not-null="true" default="1" />
    </version>
    <any id-type="System.Int64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" meta-type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" name="HusbandBanan">
      <meta-value value="MotherBanan" class="LittleNHibernateProject.Model.MotherBanan, LittleNHibernateProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      <meta-value value="FatherBanan" class="LittleNHibernateProject.Model.FatherBanan, LittleNHibernateProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      <column name="Banan_Type" />
      <column name="Banan_Id" />
    </any>
    <property name="Variety" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Variety" />
    </property>
  </class>
</hibernate-mapping>

我只需要 select 加载标识符的根实体和内部实体(并且我使用 statlesssession)。 如果我想 select FatherBanan 我使用扩展名:

public static List<FatherBanan> ToOnlyRefList(this IQueryable<FatherBanan> query)
        {
            var select = query.Select(sel => new {sel.Id, sel.Name, sel.Variety, WifeId = sel.WifeBanan.Id, sel.VersionObject}).ToList();

            var result = new List<FatherBanan>();
            foreach (var item in select)
            {
                result.Add(new FatherBanan
                {
                    Id = item.Id,
                    Name = item.Name,
                    Variety = item.Variety,
                    VersionObject = item.VersionObject,
                    WifeBanan = new MotherBanan{Id = item.WifeId}
                });
            }

            return result;
        }

Select巴南爸爸:

                using (var sss = factorySession.OpenSession())
                {
                    var list = sss.Query<FatherBanan>().ToOnlyRefList();
                }

并且 Nhibernate 从 table FatherBanan 生成 SQL,没问题。

但是如果我想 select JobBanan:表达式 select new 不起作用,生成异常不要将 JobBanan 转换为 Banan。好的,通过使用扩展解决了它的异常:

public static List<JobBanan> ToOnlyRefList(this IQueryOver<JobBanan, JobBanan> query)
        {
            var select = query
                .Select(
                Projections.Property("Id"),
                Projections.Property("JobName"),
                Projections.Property("VersionObject"),
                Projections.SqlProjection("banan_id as banan_id", new[] { "banan_id" }, new IType[] { NHibernateUtil.Int64 }),
                Projections.SqlProjection("banan_type as banan_type", new[] { "banan_type" }, new IType[] { NHibernateUtil.String })
                ).List<object[]>();

            var result = new List<JobBanan>();
            foreach (var item in select)
            {
                Banan banan = null;

                if (item[4] as string == nameof(FatherBanan))
                {
                    banan = new FatherBanan() { Id = (long)item[3] };
                }
                else
                if (item[4] as string == nameof(MotherBanan))
                {
                    banan = new MotherBanan { Id = (long)item[3] };
                }

                result.Add(new JobBanan
                {
                    Id = (long)item[0],
                    JobName = (string)item[1],
                    VersionObject = (long)item[2],
                    Banan = banan
                });
            }

            return result;
        }

我得到所有的巴南sss.Query<Banan>.ToOnlyRefList()?

我找到了一种方法 - 只需将所有内容嵌套在循环中即可:

var types = new Type[]{/*all type in Any mapping Banan*/};
var result = new List<Banan>();
foreach(var type in types)
{
    result.AddRange(sss.Query(type.FullName).ToOnlyRefList());
}

如果实体(和内部实体)不是抽象的,那么:


using (var session = factorySession.OpenSession())
            {
                var banan = 
                    session
                        .Query<CompanyBanan>()
                        .Select( sel => new
                        {
                            sel.Id,
                            BananId = sel.FatherBanan == null ? (long?)null : sel.FatherBanan.Id,
                            sel.Name,
                            sel.VersionObject
                        })
                        .ToList()
                    ;
            }
//and convert typle to entity extension

这会生成 SQL:

select
    companyban0_.Id as col_0_0_, case when fatherbana1_.Id is null then TRUE else FALSE end as col_1_0_, companyban0_.FatherBanan_id as col_2_0_, companyban0_.Name as col_3_0_, companyban0_.VersionObject as col_4_0_ 
from CompanyBanan companyban0_
left outer join FatherBanan fatherbana1_ on companyban0_.FatherBanan_id=fatherbana1_.Id