我发现了两个类似的问题:
根据this page:
小心不要急切地取 多个集合属性 同时。虽然这句话 工作正常:
var employees = session.Query<Employee>() .Fetch(e => e.Subordinates) .Fetch(e => e.Orders).ToList();
执行笛卡尔积查询 对数据库,所以总 返回的行数将是 总下属总数 订单。
假设我有以下型号:
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(不返回笛卡尔积)急切地使用其书籍,文章和地址加载所有人的最简单方法是什么?
由于
更新
请参阅下面的cremor的answer和Florian Lim中answer的this thread。以下代码很好地工作,只有一次往返数据库。
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>();
答案 0 :(得分:1)
如果你使用的是更新版本的nhibernate(&gt; = 4.0),我更喜欢使用linq提供程序。只要您将您的集合映射为ISets(需要.net framework&gt; = 4),我们将其转换为我们可以进行急切加载并避免使用笛卡尔积。我觉得这不是一个广告宣传的东西,但我更喜欢这种适用于其他任何方法的方法:
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>();
}
如果您的集合定义如上,那么您可以执行以下操作并仍然避免使用笛卡尔产品问题:
var persons = session.Query<Person>()
.FetchMany(x => x.Books)
.FetchMany(x => x.Articles)
.FetchMany(x => x.Addresses)
.ToList();
答案 1 :(得分:-2)
public IList<Person> GetAll()
{
var persons = session.QueryOver<Person>()
.Future<Person>();
session.QueryOver<Person>()
.Fetch(x => x.Books).Eager
.Future<Person>();
session.QueryOver<Person>()
.Fetch(x => x.Articles).Eager
.Future<Person>();
session.QueryOver<Person>()
.Fetch(x => x.Addresses).Eager
.Future<Person>();
return persons.ToList();
}