我有以下型号
public class Customer
{
public virtual long Id { get; set; }
public virtual string Name { get; set; }
public virtual IList<Invoice> Invoices { get; set; }
public virtual XDocument AlotOfData { get; set; }
}
public class Invoice
{
public virtual long CustomerId { get; set; }
public virtual long Id { get; set; }
public virtual IList<LineItem> LineItems { get; set; }
public virtual XDocument AlotOfData { get; set; }
}
public class LineItem
{
public virtual long InvoiceId { get; set; }
public virtual long Id { get; set; }
public virtual double Amount { get; set; }
public virtual XDocument AlotOfData { get; set; }
}
如果我只是通过正常的nhibernate查询来获取客户,那么它将如下所示。
long customerId = 1;
Customer customer = Session.QueryOver<Customer>().Where(x => x.Id == customerId).SingleOrDefault();
如果我在所有子集合的映射文件中都有lazy =“false”,则会导致执行以下Sql查询
获取客户的1个查询(仅从Customer表中选择列)
获取该客户的所有发票的1个查询(仅从发票表中选择列)
n对LineItems表的查询(每个Invoice的一个查询仅选择LineItems表中的列)
我想知道的是我如何保持当前正在执行的相同查询,而不是nhibernate对LineItems表进行n个单独的查询,它只会使1.有没有办法可以做到这一点通过in子句或联接到发票表但不从发票表中选择列。
由于 杰里米
答案 0 :(得分:1)
是的NHibernate支持此功能,它被称为:
让我引用文档:
NHibernate可以有效地使用批量提取,也就是说,如果访问一个代理(或集合),NHibernate可以加载几个未初始化的代理。批量提取是懒惰选择提取策略的优化。有两种方法可以调整批处理获取:在类和集合级别上。
更容易理解批量提取类/实体。想象一下,您在运行时遇到以下情况:您在一个ISession中加载了25个Cat实例,每个Cat都有一个对其所有者的引用,一个Person。 Person类使用代理映射,lazy =“true”。如果您现在遍历所有猫并在每个猫上调用cat.Owner,NHibernate将默认执行25个SELECT语句,以检索代理所有者。您可以通过在Person:
的映射中指定批量大小来调整此行为
<class name="Person" batch-size="10">...</class>
NHibernate现在只执行三个查询,模式是10,10,5 .... ...
batch-size="25"
设置也可用于集合映射:
您还可以启用批量提取集合。例如,如果每个Person都有一个懒惰的Cats集合,并且当前在ISesssion中加载了10个人,则遍历所有人将生成10个SELECT,每个人调用一个SELECT.Cats。如果在Person的映射中为Cats集合启用批量获取,NHibernate可以预取集合:
<class name="Person">
<set name="Cats" batch-size="3">
...
</set>
</class>
我强烈建议使用它。我确实在每个类和集合上都有映射
另见: