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所期望的吗?

Nhibernate SetFetchMode-内部连接与左外部连接

您所经历的是绝对正确的。你的解决方案真的很合适。

呼叫:

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)

这将达到预期。。。