【问题标题】:Eagerly fetch multiple collection properties (using QueryOver/Linq)?急切地获取多个集合属性(使用 QueryOver/Linq)?
【发布时间】:2011-08-14 10:29:57
【问题描述】:

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

根据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 急切地加载所有人的书籍、文章和地址的最简单方法是什么(不返回笛卡尔积)?

谢谢


更新:

请参阅下面的cremoranswerthis threadFlorian Limanswer。以下代码运行良好,只需往返数据库一次。

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

【问题讨论】:

    标签: nhibernate linq-to-nhibernate queryover


    【解决方案1】:
    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();
    }
    

    【讨论】:

    • 请添加说明您所做的事情
    【解决方案2】:

    如果可能的话,我更喜欢使用 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();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-24
      • 1970-01-01
      • 2012-12-17
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      • 2012-07-07
      相关资源
      最近更新 更多