我有一个看起来像这样的类:
[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 View 有一个 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 对这两个执行连接?
最佳答案
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
中定义)作为不同的关系进行评估。现在将使用单个 select 语句
每当 formula
用于映射(而不是 column
)时,它应该被标记为 insert="false"
和 更新=“假”
。我们只需要它来进行 SELECT。 (否则我们可以将具有不同 ClientId 的 Client 和 ClientReportSummary 附加到 SessionReportSummaries 实体 - 这将违反异常...
第二种方法可以是一对一映射,其中“ClientId”在所有三个表中应该是完全相同的……但这是另一个话题
关于c# - 同一列上的多个多对一连接错误地导致执行 SELECT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13295765/