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
我的 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