渴望获取多个集合属性(使用QueryOver/Linq)? [英] Eagerly fetch multiple collection properties (using QueryOver/Linq)?
问题描述
我发现了2个类似的问题:
I found 2 similar questions:
- Multiple Fetches in linq to nhibernate
- Is this the right way of using ThenFetch() to load multiple collections?
根据此页面:>
注意不要急于获取 处的多个集合属性 同时.虽然这句话 会正常工作:
Be careful not to eagerly fetch multiple collection properties at the same time. Although this statement will work fine:
var employees = session.Query<Employee>()
.Fetch(e => e.Subordinates)
.Fetch(e => e.Orders).ToList();
执行笛卡尔乘积查询 针对数据库,因此总计 返回的行数将是 下属总数乘以总数 订单.
It executes a Cartesian product query against the database, so the total number of rows returned will be the total Subordinates times the total orders.
让我们说我有以下模型:
Lets say I have the following model:
public class Person
{
public virtual int Id { get; private set; }
public virtual ICollection<Book> Books { get; set; }
public virtual ICollection<Article> Articles { get; set; }
public virtual ICollection<Address> Addresses { get; set; }
}
使用QueryOver/Linq(不返回笛卡尔积)向所有人热切加载其书籍,文章和地址的最简单方法是什么?
What is the simplest way to eagerly load all persons with their Books, Articles, and Addresses using QueryOver/Linq (without returning a Cartesian product)?
谢谢
更新:
请参见 cremor 的 Florian Lim 在答案 href ="https://stackoverflow.com/questions/5682668/how-to-resolve-poor-nhibernate-collection-initialization">此线程.以下代码运行良好,仅需往返数据库一次即可.
See cremor's answer below and Florian Lim's answer in this thread. The following code works nicely, only one round-trip to the database.
var persons = session.QueryOver<Person>()
.Future<Person>();
var persons2 = session.QueryOver<Person>()
.Fetch(x => x.Books).Eager
.Future<Person>();
var persons3 = session.QueryOver<Person>()
.Fetch(x => x.Articles).Eager
.Future<Person>();
var persons4 = session.QueryOver<Person>()
.Fetch(x => x.Addresses).Eager
.Future<Person>();
推荐答案
如果可能的话,我更喜欢使用linq提供程序,尤其是在使用较新版本的nhibernate(> = 4.0)的情况下.只要您将集合映射为ISets(需要.net framework> = 4),然后将其转换为ISets,我们就可以进行急切的加载并避免使用笛卡尔积.我觉得这不是广为宣传的东西,但我更喜欢这种方法,而不是其他任何方法:
I prefer to use the linq provider if at all possible especially if you are using newer versions of nhibernate (>= 4.0). As long as you have your collections mapped as ISets (requires .net framework >= 4) which we converted to such that we could do eager loading and avoid cartesian products. I feel like this isn't something that is heavily advertised but I prefer this method where applicable over anything else :
public class Person
{
public virtual int Id { get; private set; }
public virtual ISet<Book> Books { get; set; }
public virtual ISet<Article> Articles { get; set; }
public virtual ISet<Address> Addresses { get; set; }
}
public Person()
{
this.Books = new HashSet<Book>();
this.Articles = new HashSet<Article>();
this.Addresses = new HashSet<Address>();
}
如果您按照上述方式定义了集合,则可以执行以下操作,并且仍然可以避免笛卡尔积问题:
If you have your collections defined like the above then you can do the following and still avoid cartesian product issues:
var persons = session.Query<Person>()
.FetchMany(x => x.Books)
.FetchMany(x => x.Articles)
.FetchMany(x => x.Addresses)
.ToList();
这篇关于渴望获取多个集合属性(使用QueryOver/Linq)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!