36

我发现了2个类似的问题:

根据此页面

注意不要急切地同时获取多个集合属性。尽管此语句可以正常工作:

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回答Florian Lim此线程中的回答。以下代码运行良好,只需往返数据库一次。

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>();
4

2 回答 2

5

如果可能的话,我更喜欢使用 linq 提供程序,特别是如果您使用更新版本的 nhibernate (>= 4.0)。只要您将您的集合映射为 ISet(需要 .net 框架 >= 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();
于 2016-12-16T13:22:38.577 回答
-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();
}
于 2016-08-03T03:14:44.377 回答