nHibernate.IQueryOver 删除子 class 左连接
nHibernate.IQueryOver removing sub class left join
我有两个对象(BagDto
和 ItemDto
)之间的内部连接查询,其中 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; }
}
在我的查询中,我不想获取任何类型的位置数据,只有 BagDto
和 ItemDto
才是我真正想要查询的。所有三个对象的映射都没有问题,我不想更改它们。我也不想创建继承来将 LocationDto
分开(即:ItemDto
不会包含 LocationDto
但 ItemWithLocationDto
会)。
这里是查询:
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
我有两个对象(BagDto
和 ItemDto
)之间的内部连接查询,其中 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; }
}
在我的查询中,我不想获取任何类型的位置数据,只有 BagDto
和 ItemDto
才是我真正想要查询的。所有三个对象的映射都没有问题,我不想更改它们。我也不想创建继承来将 LocationDto
分开(即:ItemDto
不会包含 LocationDto
但 ItemWithLocationDto
会)。
这里是查询:
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