Nhibernate SetFetchMode-内部连接与左外部连接
本文关键字:连接 外部 Nhibernate 内部 SetFetchMode- | 更新日期: 2023-09-27 18:22:33
全部,
我有一个叫Client的实体,它与一个叫Region的实体有关联,称为:
客户->区域
我的所有实体都是Lazy加载的(nhibernate默认设置)。
客户端中的区域映射为NotNull=false:
[ManyToOne(Column = "region_id",
ClassType = typeof(Region),
NotNull = false)]
public virtual Region Region
{
get { return _region; }
set { _region = value; }
}
当我创建客户端条件并设置FetchMode(FetchMode.Join)时,生成的select是内部联接,但我期望并保留外部联接,因为Region可以为NULL。
以上情况取决于条件的创建方式。如果我像Ex1中那样创建条件,我会生成正确的SQL,并且Region是外部联接的;如果我像ex2中那样创建标准,我会产生不正确的SQL;Region是内部联接的。
示例1)正确的SQL
ICriteria c = s.Session.CreateCriteria<Client>();
c.SetFetchMode("Region", NHibernate.FetchMode.Join);
IList<Client> list2 = c.List<Client>();
SELECT * FROM Companies this_ left outer join Code_Region_Types region2_ on this_.region_id=region2_.entity_id
示例2)错误的SQL
ICriteria c = s.Session.CreateCriteria<Client>();
ICriteria subC = c.CreateCriteria("Region");
c.SetFetchMode("Region", NHibernate.FetchMode.Join);
IList<Client> list2 = c.List<Client>();
SELECT * FROM Companies this_ inner join Code_Region_Types region1_ on this_.region_id=region1_.entity_id
在ex2)中,创建子标准的行
ICriteria subC = c.CreateCriteria("Region");
把联接子句搞砸了。
这会产生不正确的结果,因为某些客户端可能没有Region,因此不包括在查询中。
似乎唯一的解决方案是在子标准上明确指定联接:
ICriteria subC = c.CreateCriteria("Region", JoinType.LeftOuterJoin)
以上解决了问题。这是Nhibernate所期望的吗?
您所经历的是绝对正确的。你的解决方案真的很合适。
呼叫:
criteria.CreateCriteria(associationPath);
事实上,内部确实使用了INNER JOIN(请参阅此处):
public ICriteria CreateCriteria(string associationPath)
{
return CreateCriteria(associationPath, JoinType.InnerJoin);
}
因此,通过这种方式定义查询。它将是INNER JOIN。Fetch模式由Criteria及其SubCriteria的结果驱动,即只考虑找到的结果。
但正如你所发现的,我们可以简单地通过显式调用来改变这一点:
ICriteria subCriteria = criteria
.CreateCriteria(associationPath, JoinType.LeftOuterJoin)
这将达到预期。。。