我想要一个按一些标准搜索的购买列表。 购买实体包含一个产品。 这是映射:
<class name="Product" table="Products">
<id name="Id">
<generator class="identity"></generator>
</id>
<property name="Name"></property>
<many-to-one name="Brand" column="BrandId" lazy="false" fetch="join" />
<many-to-one name="Category" column="CategoryId" lazy="false" fetch="join" />
</class>
<class name="Shop" table="Shops">
<id name="Id">
<generator class="identity"></generator>
</id>
<property name="Name"></property>
</class>
<class name="Purchase" table="Purchases" lazy="false">
<id name="Id">
<generator class="identity"></generator>
</id>
<many-to-one name="Product" column="ProductId" lazy="false" fetch="join" />
<many-to-one name="Shop" column="ShopId" lazy="false" fetch="join" />
</class>
这就是我执行搜索的方式:
string query = string.Format(@"
select pc from Purchase as pc
inner join pc.Product as p
left outer join p.Brand as b
where
{0} and {1}
and
(
(p.Name like '%{2}%')
or (b.Name like '%{2}%')
)
",
filters.From.HasValue ? "pc.Date >= " + SqlHelper.GetSqlDate(filters.From) : "1=1",
filters.To.HasValue ? "pc.Date <= " + SqlHelper.GetSqlDate(filters.To) : "1=1",
filters.Text);
var list = session.CreateQuery(query)
.List<Purchase>(); //.Future<Purchase>().ToList();
返回列表;
(我没有删除查询中的其他过滤器只是为了#34;显示&#34;一个简单的Get / Query / QueryOver是不可能的(它不能作为SQL或HQL读取)
可以改进......但问题在于此代码为购买列表生成1个查询,对于商店的产品加M个查询生成N个查询,例如执行251或770个查询而不是一个。
我认为由于lazy="false"
关系上的many-to-one
,只执行了一个查询。
为什么NHibernate会在每次购买时对Product(和Shop)进行查询? 我可以更改映射以获得一个查询的执行吗?
谢谢, 的Alessandro
答案 0 :(得分:0)
HQL不尊重fetch="join"
(在映射中)。我明确表示在联接中添加fetch
:
select pc from Purchase as pc
inner join **fetch** pc.Product as p
left outer join **fetch** p.Brand as b
...并且它有效:只执行一个查询。