【问题标题】:Select columns from join table only without requiring a join仅从连接表中选择列而不需要连接
【发布时间】:2010-03-22 10:04:42
【问题描述】:

鉴于这些表格:

create table Orders (
   Id INT IDENTITY NOT NULL,
   primary key (Id)
)

create table Items (
   Id INT IDENTITY NOT NULL,
   primary key (Id)
)

create table OrdersItems (
   OrderId INT not null,
   ItemId INT not null,
   primary key (OrderId, ItemId)
)

是否可以使用 HQL/criteria API 来构造一个导致以下 SQL 的查询:

SELECT
    [OrderId], [ItemId]
FROM
    [OrdersItems]

这两种方法我都试过了:

var hqlResults = session
    .CreateQuery("select order.id, item.id from Order order inner join order.Items item")
    .List();

var criteriaResults = session
    .CreateCriteria<Order>()
    .CreateAlias("Items", "item", NHibernate.SqlCommand.JoinType.None)
    .SetProjection(Projections.Property("id"), Projections.Property("item.id"))
    .List();

但是这两种方法都坚持生成一个连接(或者在使用条件时因为连接不存在而失败),导致 SQL 如下:

select order.Id,
       item.Id
from   Orders order
       inner join OrdersItems ordersItems
         on order.Id = ordersItems.ArticleId
       inner join Items item
         on ordersItems.CategoryId = item.Id

有什么方法可以让 NHibernate 生成一个查询,只从连接表中选择列,而不需要连接?

【问题讨论】:

  • 您打算使用 Items 表进行排序还是过滤?如果只是过滤,那么 DetachedCriteria 就是要走的路。
  • @Kent - 澄清一下,OrdersItems 没有类,对吧?如果有,我认为这将是直截了当的。
  • @Michael:没错——没有明确的类/映射。理论上我可以创建一个,但我不愿意针对这种特殊情况。

标签: sql nhibernate hql criteria-api


【解决方案1】:

我怀疑是否有使用 HQL 的方法,因为 HQL 与 NHibernate 实体进行交易,而 OrderItems 不是实体。在这种情况下,看起来您实际上并没有使用任何 ORM 功能,因此您可以简单地执行 SQL 查询 - 如果您愿意,可以通过 NHibernate。只需致电ISession.CreateSQLQuery()

编辑

怀疑 NHibernate 坚持执行连接的原因是:您已经向它询问了 OrderItem 实体的 Id 属性,因此它必须确保OrderItem 表中实际上有这些 ID 的行。 OrderItems 表中可能存在一行,其 ID 在 OrderItem 中不存在。当然,这样做是糟糕的数据库设计,而且不太可能,但是 NHibernate 不能确定情况并非如此,除非它查看表模式并看到适当的外键 - 但我怀疑它是否会做类似的事情那个。

不过,这只是我的猜测。您可以在NHibernate forum 上向开发人员询问更明确的答案。

【讨论】:

  • 我目前正在使用 SQL 查询。我希望转移到标准 API 或至少 HQL 以简化我的代码。我知道在这种情况下我可能对 NHibernate 要求太多,但如果我只要求连接表中存在的列,它可能足够聪明,可以省略连接。跨度>
  • 关于您的编辑,我实际上使用的是特殊的“id”而不是“Id”。这应该是为了鼓励 NH 避免加入。如果我使用“ForeignEntity.id”而不是“ForeignEntity.Id”从表中选择 FK,它将不会加入外部表,而只会选择父表中的外部列。因此,在这种情况下,它也不能验证记录是否确实存在。嗯...
  • 接受为答案。从我尝试和阅读的所有内容中,我得出结论,答案是“不”。我正在使用 SQL 查询。哦,好吧。
猜你喜欢
  • 2022-01-03
  • 1970-01-01
  • 2020-04-27
  • 2018-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-30
  • 2013-07-11
  • 1970-01-01
相关资源
最近更新 更多