NHibernate执行无关的select语句

时间:2009-10-26 04:09:44

标签: nhibernate nhibernate-mapping

问题

当为具有多对一关系的实体执行get时,外连接设置为true,not-found设置为ignore并且一侧的实体行不存在,NHibernate执行额外的select尝试加载它,即使之前刚刚执行的选择找不到它。

问题

为什么执行这个额外的选择并且有什么方法可以抑制它?

上下文

我正在使用没有外键约束的遗留数据库,我无法控制架构。不幸的是,修改它是不可能的。请记住,我的实际映射比这更复杂。对于实际实体,这种情况会多次发生,并且它们通常由ICriteria.List<T>()而不是Session.Load<T>(id)加载,从而导致大量不必要的查询和大的性能损失。

简化示例


ISession Session = ...
...
Session.Get<Bid>(1);
...
执行SQL
SELECT bid.Id, bid.ItemId, item.Id FROM Bid bid left outer join Item item on bid.ItemId=item.Id WHERE bid.Id=@p0;@p0 = 1
SELECT item.Id FROM Item item WHERE item.Id=@p0;@p0 = 222
制图
<?xml version="1.0" encoding="utf-8" ?>  
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Example" namespace="Example">  
   <class name="Bid">  
     <id name="Id">  
       <generator class="native"/>  
     </id>  
     <many-to-one name="Item" column="ItemId" outer-join="true" not-found="ignore" />  
   </class>  
   <class name="Item">  
     <id name="Id">  
       <generator class="native"/>  
     </id>  
   </class>  
 </hibernate-mapping>  
投标表内容
Id  ItemId    
1   222  
项目表内容
Id  
333  
444  

2 个答案:

答案 0 :(得分:1)

好的,看起来它肯定是NHibernate中的一个错误,你可以看到here。目前,它被标记为次要的,所以我猜投票可能会提高它的形象并得到修复。

答案 1 :(得分:0)

如果不进行此设置,我猜测关键是在多对一关联中用fetch =“join”替换outer-join =“true”。默认情况下,多对一关联的获取模式为“select”,我怀疑这会导致select被执行。

如果您将该映射修改为:

 <many-to-one name="Item" column="ItemId" fetch="join" not-found="ignore" />  

它应该表现得更像你期望的那样。