【问题标题】:Nhibernate SetFetchMode - Inner vs Left Outer JoinNhibernate SetFetchMode - 内连接与左外连接
【发布时间】:2014-09-18 17:51:16
【问题描述】:

全部,

我有一个名为 Client 的实体,它与一个名为 Region 的实体有关联:

客户 -> 地区

我所有的实体都是延迟加载的(nhibernate 默认设置)。

Client 中的 Region 映射为 NotNull = false:

[ManyToOne(Column = "region_id",
                ClassType = typeof(Region),
                NotNull = false)]
    public virtual Region Region
    {
        get { return _region; }
        set { _region = value; }
    }

当我创建客户端条件并设置 FetchMode(FetchMode.Join) 时,生成的选择是内连接,但我期望并离开外连接,因为 Region 可以为 NULL。

上述情况取决于标准的创建方式。如果我在示例 1 中创建条件,我会生成正确的 SQL,并且区域是左外连接,如果我在示例 2 中创建条件,我会生成不正确的 SQL,区域是内连接。

例 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

Ex 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

在 ex 2) 中,创建子标准的行

ICriteria subC = c.CreateCriteria("Region");

弄乱了连接子句。

这会产生不正确的结果,因为某些客户端可能没有区域,因此不包含在查询中。

看来唯一的解决办法是明确指定子标准的连接:

ICriteria subC = c.CreateCriteria("Region", JoinType.LeftOuterJoin)

以上解决了这个问题。这是 Nhibernate 所期望的吗?

【问题讨论】:

    标签: c# nhibernate nhibernate-mapping nhibernate-criteria


    【解决方案1】:

    你所经历的是绝对正确的。而且您的解决方案确实是正确的。

    调用:

    criteria.CreateCriteria(associationPath); 
    

    实际上在内部确实使用了 INNER JOIN(参见 here):

    public ICriteria CreateCriteria(string associationPath)
    {
        return CreateCriteria(associationPath, JoinType.InnerJoin);
    }
    

    所以,这样定义了查询。这将是 INNER JOIN。然后,Fetch 模式由该 Criteria 及其 SubCriteria 的结果驱动 - 即仅考虑 found 结果。

    但正如您所发现的,我们可以通过显式调用来简单地改变它:

    ICriteria subCriteria = criteria
         .CreateCriteria(associationPath, JoinType.LeftOuterJoin)
    

    这将达到预期的效果......

    【讨论】:

      猜你喜欢
      • 2011-02-14
      • 1970-01-01
      • 2011-10-01
      • 1970-01-01
      • 2021-09-02
      • 1970-01-01
      • 2015-01-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多