7

我有一个看起来像这样的类:

[Class(Table = "SessionReportSummaries", Mutable = false)]
public class SessionReportSummaries
{        
    [ManyToOne(Column = "ClientId", Fetch = FetchMode.Join)]
    public Client Client { get; private set; }

    [ManyToOne(Column = "ClientId", Fetch = FetchMode.Join)]
    public ClientReportSummary ClientReportSummary { get; private set; }
}

SessionReportSummaries 视图有一个 ClientId 列,我正在尝试使用此列加入一个 Client 对象和一个 ClientReportSummary 对象。

不幸的是,NHibernate 只想加入类中定义的第一个,并且总是为第二个执行 SELECT。所以在这种情况下,NHibernate 首先查询数据库:

SELECT {stuff} FROM SessionReportSummaries ... left outer join Clients on this.ClientId=Clients.Id ...

(有很多其他连接),然后是其中的 N 个:

SELECT {stuff} FROM ClientReportSummary WHERE ClientReportSummary.ClientId = '{id goes here}'

有问题的 N 个客户中的每一个都有一个。这会导致糟糕的性能。

如果我交换 Client 和 ClientReportSummary 对象的位置,则 NHibernate 将 ClientReportSummary 加入 SessionReportSummaries 对象,并为每个 Client 对象执行选择。

有谁知道我怎样才能让 NHibernate 为这两者执行连接?

4

1 回答 1

2

NHibernate 将在单个查询中仅采用一个相同的列映射。所以,因为有两个不同的实体通过列属性映射到值“ClientId”:

  • [ManyToOne(Column = "ClientId", Fetch = FetchMode.Join)]
  • [ManyToOne(Column = "ClientId", Fetch = FetchMode.Join)]

在这种情况下,不授予列映射​​的唯一性。当插入或更新两个实体时,它可能会造成损坏。但是我们可以使用一个技巧:FORMULA映射

[Class(Table = "SessionReportSummaries", Mutable = false)]
public class SessionReportSummaries
{        
    [ManyToOne(Column = "ClientId", Fetch = FetchMode.Join)]
    public Client Client { get; private set; }

    [ManyToOne(Formula = "ClientId", Fetch = FetchMode.Join)]
    public ClientReportSummary ClientReportSummary { get; private set; }
}

现在 NHibernate 将把一个列映射作为真正的关系,并将第二个(定义在 中formula)作为不同的关系。现在将使用单个选择语句

无论何时formula用于映射(而不是column),都应标记为insert="false"update="false"。我们只需要它来进行 SELECT。(否则我们可以将具有不同 ClientId 的 Client 和 ClientReportSummary 附加到 SessionReportSummaries 实体 - 这将违反异常......

第二种方法可能是一对一映射,其中“ClientId”预计在所有三个表中都是相同的......但这是另一个主题

于 2012-11-09T09:40:23.113 回答