急切地获取多个集合属性(使用 QueryOver/Linq)? [英] Eagerly fetch multiple collection properties (using QueryOver/Linq)?

查看:19
本文介绍了急切地获取多个集合属性(使用 QueryOver/Linq)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I found 2 similar questions:

根据本页:

注意不要急切地去取多个集合属性在同时.虽然这个说法会正常工作:

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.

假设我有以下模型:

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 Limanswerhref="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) 时.只要您将集合映射为 ISet(需要 .net 框架 >= 4),我们将其转换为这样我们就可以进行急切加载并避免笛卡尔积.我觉得这不是大肆宣传的东西,但我更喜欢这种适用于其他任何方法的方法:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆