Подкачка страниц по лениво загруженному набору с NHibernate

Я прочитал эту статью, где Ayende заявляет, что NHibernate может (по сравнению с EF 4):

  • Набор с ленивым =” дополнительный” – Ленивый дополнительный означает, что NHibernate адаптируется к операциям, которые Вы могли бы выполнить сверху своих наборов. Это означает тот блог. Сообщения. Количество не вызовет загрузку всего набора, а скорее создало бы “избранное количество (*) из Сообщений где BlogId = 1” оператор и тот блог. Сообщения. Содержит (), аналогично приведет к единому запросу вместо того, чтобы платить цену загрузки всего набора к памяти.
  • Фильтры набора и разбитые на страницы наборы - это позволяет Вам определять дополнительные фильтры (включая подкачку страниц!) сверху Ваших наборов объектов, что означает, что можно легко пролистать блог. Набор сообщений, и не должен загрузить всю вещь в память.

Таким образом, я решил соединить тестовый сценарий. Я создал модель Blog клише как простую демонстрацию с двумя классами следующим образом:

public class Blog
{
    public virtual int Id { get; private set;  }
    public virtual string Name { get; set; }

    public virtual ICollection Posts { get; private set;  }

    public virtual void AddPost(Post item)
    {
        if (Posts == null) Posts = new List();
        if (!Posts.Contains(item)) Posts.Add(item);
    }
}

public class Post
{
    public virtual int Id { get; private set; }
    public virtual string Title { get; set; }
    public virtual string Body { get; set; }
    public virtual Blog Blog { get; private set; }
}

Мои файлы отображений похожи на это:


  
    
      
      
    
    
      
    
    
      
    
    
      
        
      
      
    
  



  
    
      
      
    
    
      
    
    
      
    
    
      
    
  

Мой тестовый сценарий выглядит примерно так:

        using (ISession session = Configuration.Current.CreateSession()) // this class returns a custom ISession that represents either EF4 or NHibernate
        {
            blogs = (from b in session.Linq()
                         where b.Name.Contains("Test")
                         orderby b.Id
                         select b);

            Console.WriteLine("# of Blogs containing 'Test': {0}", blogs.Count());
            Console.WriteLine("Viewing the first 5 matching Blogs.");

            foreach (Blog b in blogs.Skip(0).Take(5))
            {
                Console.WriteLine("Blog #{0} \"{1}\" has {2} Posts.", b.Id, b.Name, b.Posts.Count);
                Console.WriteLine("Viewing first 5 matching Posts.");

                foreach (Post p in b.Posts.Skip(0).Take(5))
                {
                    Console.WriteLine("Post #{0} \"{1}\" \"{2}\"", p.Id, p.Title, p.Body);
                }
            }
        }

Используя ленивый = "дополнительный", вызов к b.Posts.Count действительно делает a SELECT COUNT(Id)... который является большим. Однако b.Posts.Skip(0).Take(5) просто захваты все Сообщения для Блога. Идентификатор =? идентификатор и затем LINQ на стороне приложения просто берут первые 5 от получающегося набора.

Что дает?

13
задан HackedByChinese 12 March 2010 в 06:12
поделиться

1 ответ

Я почти уверен (читая комментарии), что он говорит о CreateFilter of ISession.

Вы можете делать разбиение по страницы следующим образом (из документов 13.13):

Collections are pageable by using the IQuery interface with a filter:

IQuery q = s.CreateFilter( collection, "" ); // the trivial filter
q.setMaxResults(PageSize); 
q.setFirstResult(PageSize * pageNumber); 
IList page = q.List();

Или (из документов 17.1.4):

s.CreateFilter( lazyCollection, "").SetFirstResult(0).SetMaxResults(10).List();

Это не так гладко, как использование методов System.Linq. Я думаю, что они тоже присоединятся к синтаксису через некоторое время.

9
ответ дан 2 December 2019 в 01:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: