NHibernate Multiquery 无需连接即可进行预加载

标签 nhibernate multi-query

是否可以使用多查询并让两个 hql 查询返回两组不同的实体,其中一组用于另一组,并且 session 通过一级缓存“修复”此问题?

例如场景(一个愚蠢的场景,可以通过连接来解决)

public class Room
{
  ...
  public virtual ISet<Bookings> Bookings {get;set;}
  public virtual bool IsAvailible {get;set;}
  ...
}

public class Booking
{
  ...
}

在执行带有两个 hql 的多条件之后:

  1. 返回所有房间 IsAvailible = true
  2. 返回所有有房间的预订,该房间有可用的房间

当从结果和预订访问房间时,我希望通过 session 的 firSTLevel 缓存 从第二个结果集中解析它们,并避免 n+1。

最佳答案

一般来说,NHibernate 可以使用缓存来“组合”通过 Multiquery 执行的查询的结果。但是,需要注意的是,这通常只适用于没有任何限制地加载惰性集合的情况。

例子:

Invoice iAlias = null;
InvoiceDetails idAlias = null;

// Base-Query: get Invoices with certain condition
var invoices = session.QueryOver<Invoice>()
    .Where(i => i.Number == "001")
    .Future<Invoice>();

// Option 1: this will still cause N+1 if we iterate through invoices,
// because it doesn't know better
var invoicedetails = session.QueryOver<InvoiceDetails>()
    .JoinAlias(a => a.Invoice, () => iAlias)
    .Where(() => iAlias.Number == "001")
    .Future<InvoiceDetails>();

// Option 2: this will still cause N+1 if we iterate through invoices,
// because we limited the possible results using a where-condition
var invoices2 = session.QueryOver<Invoice>()
    .Left.JoinAlias(i => i.Details, () => idAlias)
    .Where(i => i.Number == "001")
    .And(() => idAlias.Quantity > 5)
    .Future<Invoice>();

// Option 3: this will work without N+1, because we don't use a filter
// -> NHibernate will use the collection in cache
var invoices3 = session.QueryOver<Invoice>()
    .Left.JoinAlias(i => i.Details, () => idAlias)
    .Where(i => i.Number == "001")
    .Future<Invoice>();

foreach (Invoice i in invoices)
{
    int count = i.Details.Count;
}

如果我们注释掉三个选项中的两个并执行代码,我们将看到只有选项 3 会阻止 N+1,其他两个仍将为每个 加载 InvoiceDetails >发票在循环中。

当然这是一个非常简单的示例,很明显选项 3 也可以在没有 Base-query 的情况下执行并且仍然返回相同的结果,但我希望你明白这一点。

在我们加载两组不同实体的情况下,即根类与选项 1 中的不同,这种“组合”很可能不起作用。

抱歉,如果我使用 QueryOver 而不是 HQL,但适用相同的规则。

关于NHibernate Multiquery 无需连接即可进行预加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5634483/

相关文章:

php - 可以将 "Multiple MySQL Queries with PHP"与 MySQL 版本 4 一起使用

php - 新连接上的 MySqli 错误 2014

php - MySQL在(结构相同)多个表中搜索id

java - 共享 nHibernate 和 hibernate 二级缓存

php - 在 PHP 中运行两个 SQL 查询,其中第一个语句创建一个临时表以供第二个语句使用

c# - 用于有状态应用程序的 ORM。 EF适合吗?或者任何?

nhibernate - 一次将 1000 多条记录保存到数据库中

asp.net-mvc - 有人可以帮助我理解为什么使用 NHibernate 时自动标识 (int) 不好?

nhibernate - 使用 DTO 时,Automapper 和 Nhibernate 反射(reflect)正在更新的域对象中 DTO 子集合的变化