nHibernate.IQueryOver 删除子 class 左连接

nHibernate.IQueryOver removing sub class left join

我有两个对象(BagDtoItemDto)之间的内部连接查询,其中 ItemDto 也有至少一个类型为 LocationDto 的父对象。以下是 class 定义:

    public class BagDto
    {
        public int Id { get; set; }
        public string Color { get; set; }
        public string Type { get; set; }
        public DateTime CreatedDate { get; set; }
        /* other properties for bag comming from oracle DB */
        public IEnumerable<ItemDto> Items { get; set; }
    }

    public class ItemDto
    {
        public int Id { get; set; }
        public int BagId { get; set; }
        public int LocationId { get; set; }
        public string Type { get; set; }
        public DateTime AddDate { get; set; }
        public BagDto Bag { get; set; }
        public LocationDto Location { get; set; }
    }

    public class LocationDto
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public double SquareMeters { get; set; }
        public string CountyName { get; set; }
        public virtual IEnumerable<ItemDto> Items { get; set; }
    }

在我的查询中,我不想获取任何类型的位置数据,只有 BagDtoItemDto 才是我真正想要查询的。所有三个对象的映射都没有问题,我不想更改它们。我也不想创建继承来将 LocationDto 分开(即:ItemDto 不会包含 LocationDtoItemWithLocationDto 会)。


这里是查询:

public IEnumerable<BagDto> GetBagsWithAvailableType()
{
   ItemDto itemDtoAlias = null;
   Session.QueryOver<BagDto>()
          .Where(x.CreatedDate   <= DateTime.UtcNow)
          .JoinAlias(x => x.Items, () => itemDtoAlias, NHibernate.SqlCommand.JoinType.InnerJoin)
          .Where(
              () => itemDtoAlias.Type  == "A")
          .List();
}

使用 nHibernate Profiler 生成以下查询:

SELECT this_.ID,
   this_.COLOR,
   this_.TYPE,
   this_.CREATEDDATE,
   item1_.ID,
   item1_.BAG_ID,
   item1_.LOCATION_ID,
   location2_.ID,
   location2_.NAME,
   location2_.SQUAREMETERS,
   location2_.COUNTYNAME
FROM   BAG this_
   inner join ITEM item1_
   on this_.ID = item1_.BAG_ID
   left outer join LOCATION location2_
   on item1_.LOCATION_ID = location2_.ID
WHERE  (this_.CREATEDDATE <= TIMESTAMP '2021-04-07 16:23:54')
   and (item1_.TYPE = 'A')

有人知道如何摆脱与 LOCATION 相关的左外连接吗?我想在查询中指定它,但整天 google 仍然没有解决方案。感谢您的帮助!

P。 S.:用 SQL 简单地编写所有这些查询并从代码中调用它是一种不好的做法。我们的代码指南不允许这样做。

没有映射,不清楚为什么首先将 Location 添加到查询中。假设它是由于 Location 属性 的 fetch="join" 映射而添加的,您可以在使用 SelectMode.Skip 的查询中跳过它(自 NHibernate 5.2 起可用):

ItemDto itemDtoAlias = null;
   Session.QueryOver<BagDto>()
          .Where(x.CreatedDate   <= DateTime.UtcNow)
          .JoinAlias(x => x.Items, () => itemDtoAlias, NHibernate.SqlCommand.JoinType.InnerJoin)
          .Fetch(SelectMode.Skip, () => itemDtoAlias.Location)
...

查看所有 SelectMode 选项的说明 here