使用Fluent NHibernate时出现分页问题

3
我正在使用最新版本的NHibernate/Fluent NHibernate在MVC 4应用程序中。我通过Nuget安装了Fluent NHibernate,其版本号为1.3.0.733。NHibernate的版本号大约为3.3.x。
请注意,当我安装Fluent NHibernate版本1.2.0.712时,问题不会发生。
我有一个查询如下:
public IList<Post> Posts(int pageNo, int pageSize)
{
  return _session.Query<Post>()
                 .Where(p => p.Published)
                 .OrderByDescending(p => p.PostedOn)
                 .Skip(pageNo * pageSize)
                 .Take(pageSize)
                 .Fetch(p => p.Category)
                 .FetchMany(p => p.Tags)
                 .ToList();
}

有三个类: Post, Category 和 Tag 。在数据库中,我有15条关于 Post 的记录。当我将 pageNo 设置为0,将 pageSize 设置为10时,从上面的查询中只获取7条记录。为什么?
以下是类及其相应的映射类。 Post
  public class Post
  {
    public virtual int Id
    { get; set; }

    public virtual bool Published
    { get; set; }

    public virtual DateTime PostedOn
    { get; set; }


    public virtual Category Category
    { get; set; }

    public virtual IList<Tag> Tags
    { get; set; }
  }

类别

  public class Category
  {
    public virtual int Id
    { get; set; }

    public virtual string Name
    { get; set; }

    public virtual string Description
    { get; set; }

    public virtual IList<Post> Posts
    { get; set; }
  }

标签

  public class Tag
  {
    public virtual int Id
    { get; set; }

    public virtual string Name
    { get; set; }

    public virtual string Description
    { get; set; }

    public virtual IList<Post> Posts
    { get; set; }
  }

PostMap

  public class PostMap: ClassMap<Post>
  {
    public PostMap()
    {
      Id(x => x.Id);      
      Map(x => x.Published).Not.Nullable();
      Map(x => x.PostedOn).Not.Nullable();
      References(x => x.Category).Column("Category").Not.Nullable();
      HasManyToMany(x => x.Tags).Cascade.All().Table("PostTagMap");
    }
  }

CategoryMap

  public class CategoryMap : ClassMap<Category>
  {
    public CategoryMap()
    {
      Id(x => x.Id);
      Map(x => x.Name).Length(50).Not.Nullable();
      Map(x => x.Description).Length(200);
      HasMany(x => x.Posts).Inverse().Cascade.All().KeyColumn("Category");
    }
  }

标签映射

  public class TagMap: ClassMap<Tag>
  {
    public TagMap()
    {
      Id(x => x.Id);
      Map(x => x.Name).Length(50).Not.Nullable();
      Map(x => x.Description).Length(200);
      HasManyToMany(x => x.Posts).Cascade.All().Inverse().Table("PostTagMap");
    }
  }

请再确认一下:他们都确实是“已发布”状态吗? - Simon Whitehead
你使用的是哪个版本的NH? - hazzik
顺便提一下,设计API时最好采用(firstresult,maxresults)而不是(pageno,pagesize),因为前者更灵活。 - Oskar Berggren
@Simon 是的,所有的帖子都已经发布了。 - VJAI
1个回答

4
请查看此答案:https://dev59.com/jmzXa4cB1Zd3GeqPQB7z#13894326 问题很可能隐藏在标签集合的内联Fetch中。它将导致一个SELECT子句返回的行数比Post计数还要多。然后在这个结果集上应用Take()Skip()...所以只返回了前7篇文章,因为其中一些文章有更多的标签:

Post1 | TagA
Post2 | TagA
Post2 | TagB
..


解决方案是进行“延迟获取” - 即首先使用skip&take取出帖子。然后通过查询Post的.Fetch / .FetchMany来填充集合,丢弃结果。 - Goblin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接