我正在检索与其他表/实体有关系的nhibernate实体列表。我注意到,NHibernate不是执行连接和填充属性,而是检索实体,然后为每个属性调用select。例如,如果一个用户可以有多个角色,而我从数据库中检索了一个用户,那么Nhibernate将检索该用户,然后用另一个select语句填充角色。问题是,我想要检索,哦,比方说,一个产品列表,这些产品具有各种多对多关系,以及与具有自己关系的项目的关系。最后,我只剩下一千多个DB调用来检索30种产品的列表。
我还将默认延迟加载设置为false,因为每当我将实体列表保存到会话中时,尝试在另一个页面上检索它时都会出现错误: LazyInitializationException: not not initialize proxy
如果有人能给我一些启发,我将不胜感激。
下面是sql示例:
SELECT *
FROM Product b
LEFT JOIN Minisites mini
ON b.MinisiteId = mini.MinisiteId
LEFT JOIN TimeRanges tr
ON mini.TimeRange = tr.TimeRangeId
WHERE mini.MinisiteId = 7
OR tr.FromDate > '3/18/2010 12:00:00 AM'
ORDER BY CASE
WHEN mini.MinisiteId = 7 then 1
else 0
end
+ CASE
WHEN tr.FromDate > '3/18/2010 12:00:00 AM' then 1
else 0
end DESC这是我调用来检索产品的代码(我传入一个示例产品来创建查询,创建查询的实际代码太长而无法发布,但查询字符串基本上就是我上面发布的内容):
Session.CreateSQLQuery(GetSqlQuery(product)).AddEntity(typeof(Product)).SetResultTransformer(new DistinctRootEntityResultTransformer()).UniqueResult().List<Product>();通过该函数,我返回一个产品列表,并将其绑定到一个datalist。数据列表包含名称、公司、州等行,当您单击它时,它会打开下面的一个框,其中包含所有产品信息、清晰度、cut等。每个产品都与其他属性有关系,例如,它与用户有关系,用户与地址有关系,地址与国家有关系等。
以下是我的产品hbm文件:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="IDI.Domain" namespace="IDI.Domain.Entities" default-lazy="false">
<class name="IDI.Domain.Entities.Product,IDI.Domain" table="Product">
<id name="ProductId" column="ProductId" type="Int32">
<generator class="native"></generator>
</id>
<set name="Specialty" generic="true" table="ProductInSpecialties" cascade="save-update" lazy="false">
<key column="ProductId" not-null="true">
</key>
<many-to-many class="IDI.Domain.Entities.Specialty,IDI.Domain" column="SpecialtyId" lazy="false"> </many-to-many>
</set>
<!--Search By Rounds -->
<set name="Clarity" generic="true" table="ProductInClarity" lazy="false" >
<key column="ProductId" not-null="true">
</key>
<many-to-many class="IDI.Domain.Entities.Clarity,IDI.Domain" column="ClarityId" lazy="false" > </many-to-many>
</set>
<set name="Color" generic="true" table="ProductInColor">
<key column="ProductId" not-null="true">
</key>
<many-to-many class="IDI.Domain.Entities.Color,IDI.Domain" column="ColorId" lazy="false"> </many-to-many>
</set>
<set name="Carat" generic="true" table="ProductInCarat">
<key column="ProductId" not-null="true">
</key>
<many-to-many class="IDI.Domain.Entities.Carat,IDI.Domain" column="CaratId" lazy="false"> </many-to-many>
</set>
<set name="Finish" generic="true" table="ProductInFinish" >
<key column="ProductId" not-null="true">
</key>
<many-to-many class="IDI.Domain.Entities.Finish,IDI.Domain" column="FinishId" lazy="false"> </many-to-many>
</set>
<!--End Search By Rounds -->
<!--Search By Fancy Cut -->
<set name="FCShape" generic="true" table="ProductInShapes">
<key column="ProductId" not-null="true">
</key>
<many-to-many class="IDI.Domain.Entities.Shape,IDI.Domain" column="ShapeId" lazy="false"> </many-to-many>
</set>
<set name="FCClarity" generic="true" table="ProductInFCClarity">
<key column="ProductId" not-null="true">
</key>
<many-to-many class="IDI.Domain.Entities.Clarity,IDI.Domain" column="ClarityId" lazy="false"> </many-to-many>
</set>
<set name="FCColor" generic="true" table="ProductInFCColor">
<key column="ProductId" not-null="true">
</key>
<many-to-many class="IDI.Domain.Entities.Color,IDI.Domain" column="ColorId" lazy="false"> </many-to-many>
</set>
<set name="FCCarat" generic="true" table="ProductInFCCarat">
<key column="ProductId" not-null="true">
</key>
<many-to-many class="IDI.Domain.Entities.Carat,IDI.Domain" column="CaratId" lazy="false" > </many-to-many>
</set>
<set name="FCFinish" generic="true" table="ProductInFCFinish">
<key column="ProductId" not-null="true">
</key>
<many-to-many class="IDI.Domain.Entities.Finish,IDI.Domain" column="FinishId" lazy="false" > </many-to-many>
</set>
<!--End Search By Fancy Cut -->
<set name="TurnOver" generic="true" table="ProductInTurnOver" lazy="false">
<key column="ProductId" not-null="true">
</key>
<many-to-many class="IDI.Domain.Entities.TurnOver,IDI.Domain" column="TurnOverId" lazy="false"> </many-to-many>
</set>
<many-to-one name="User" column="UserId" not-null="true" cascade="save-update" lazy="false" class="IDI.Domain.Entities.BursaUser,IDI.Domain"></many-to-one>
<many-to-one name="Minisite" column="MinisiteId" not-null="false" lazy="false" class="IDI.Domain.Entities.Minisite,IDI.Domain"></many-to-one>
</class>
</hibernate-mapping>谢谢。
伊坦
发布于 2010-05-12 18:44:48
编辑
由于您自己指定了SQL查询,因此NHibernate对执行任何连接的查询没有任何影响。
您可以在实体本身的map元素或class元素上指定批处理大小(不确定)。如果NHibernate认为这会有所帮助,它会做一些基本的优化和预取记录。
(旧答案)
这是可配置的。方法,取决于配置类型(hbm、属性、fluent)。在XML中,您可以指定
fetch属性:<many-to-one fetch="join" [...] />,但问题是,如果您连接了太多的关系,这可能会导致笛卡尔乘积。还可以使用ICriteria API在每个查询的基础上设置fetchmode。如果您正在获取如此多的数据,那么只需想一想:真的有必要每次都获取所有数据吗?您是否将所有内容都报告给用户?如果没有,您可以将lazy设置为false,并仅在需要时获取数据。
https://stackoverflow.com/questions/2817493
复制相似问题