NHibernate QueryOver删除重复项

时间:2018-10-12 22:59:45

标签: c# linq nhibernate

我正在使用一个供稿系统,其中需要显示一定数量的供稿,然后单击“加载更多”按钮以显示更多供稿。

因此,我已经定义了许多行要从数据库中获取(获取),并且每当我按下“加载更多”按钮时,我都会发送跳过号(已经显示的提要数)。问题是我的查询中出现重复的行。

我想使用DISTINCT之类的东西来跳过那些重复项,所以我读到我应该使用TransformUsing(Transformers.DistinctRootEntity),但是该函数在代码端而不在db端起作用,因此,当我尝试应用时跳过并采取,提要的数量是错误的。假设我有5个供稿,但是我有2个重复,因此当我应用take函数时,结果只有4个供稿。

这是我的代码,感谢您的帮助

public IList<FeedBO> GetFeedsByUserSkills(int companyId, List<SkillBO> userSkills, int? skip = null, int? take = null)
    {
        FeedSkillBO feedSkillAlias = null;
        var query = session.QueryOver<FeedBO>()
               .JoinAlias(x => x.FeedSkills, () => feedSkillAlias)
               .Where(Restrictions.Disjunction()
                .Add(Restrictions.Conjunction()
                    .Add(Restrictions.On(() => feedSkillAlias.Skill).IsIn(userSkills))
                    .Add(Restrictions.Eq("Company.Id", companyId)))
                .Add(Restrictions.Eq("Scope", Constants.FEED_SCOPE_GLOBAL)))
                .TransformUsing(Transformers.DistinctRootEntity);

        if (skip.HasValue) query.Skip(skip.Value);
        if (take.HasValue) query.Take(take.Value);

        var sql = GetGeneratedSql(query);

        return query.OrderBy(NHibernate.Criterion.Projections.Property("CreationDate")).Desc.List();
    }

更新 我放弃了Transform,现在尝试通过以下方式进行分组:

var query = session.QueryOver<FeedBO>()
               .JoinAlias(x => x.FeedSkills, () => feedSkillAlias)
               .Where(Restrictions.Disjunction()
                .Add(Restrictions.Conjunction()
                    .Add(Restrictions.On(() => feedSkillAlias.Skill).IsIn(userSkills))
                    .Add(Restrictions.Eq("Company.Id", companyId)))
                .Add(Restrictions.Eq("Scope", Constants.FEED_SCOPE_GLOBAL)))
                .Select(
                    Projections.Distinct(
                        Projections.ProjectionList()
                            .Add(Projections.Property<FeedBO>(x => x.Id).As("Id"))
                            .Add(Projections.Property<FeedBO>(x => x.Uuid).As("Uuid"))
                            .Add(Projections.Property<FeedBO>(x => x.Title).As("Title"))
                            .Add(Projections.Property<FeedBO>(x => x.Content).As("Content"))
                            .Add(Projections.Property<FeedBO>(x => x.Link).As("Link"))
                            .Add(Projections.Property<FeedBO>(x => x.ImagePreview).As("ImagePreview"))
                            .Add(Projections.Property<FeedBO>(x => x.Scope).As("Scope"))
                            .Add(Projections.Property<FeedBO>(x => x.EventDate).As("EventDate"))
                            .Add(Projections.Property<FeedBO>(x => x.CreationDate).As("CreationDate"))
                            .Add(Projections.Property<FeedBO>(x => x.CreationUser).As("CreationUser"))
                            .Add(Projections.Property<FeedBO>(x => x.Active).As("Active"))
                            .Add(Projections.Property<FeedBO>(x => x.Company).As("Company"))
                            .Add(Projections.Property<FeedBO>(x => x.FeedSkills).As("FeedSkills"))
                            .Add(Projections.Property<FeedBO>(x => x.Likes).As("Likes"))
                    )
                ).TransformUsing(Transformers.AliasToBeanConstructor(typeof(FeedBO).GetConstructors().First()))
                .OrderBy(NHibernate.Criterion.Projections.Property("CreationDate")).Desc;

        if (skip.HasValue) query.Skip(skip.Value);
        if (take.HasValue) query.Take(take.Value);

这将生成以下SQL:

SELECT distinct this_.id as y0_, this_.uuid as y1_, this_.title as y2_, this_.content as y3_, this_.link as y4_, this_.image_preview as y5_, this_.scope as y6_, this_.event_date as y7_, this_.creation_date as y8_, this_.creation_user_id as y9_, this_.active as y10_, this_.company_id as y11_, this_.id as y12_, this_.id as y12_ 
FROM dbo.FEED this_ inner join dbo.FEED_SKILL feedskilla1_ on this_.id=feedskilla1_.feed_id 
WHERE ((feedskilla1_.skill_id in (2, 1, 24) and this_.company_id = 1) or this_.scope = 'global') 
ORDER BY this_.creation_date desc OFFSET 0 ROWS FETCH FIRST 5 ROWS ONLY

如果我直接在db中运行它会起作用,但是当我运行程序时,它将引发此异常

  

索引超出了数组的范围

我不知道该怎么办,帮忙!!!!

1 个答案:

答案 0 :(得分:0)

导入nHibernate.Linq 将QueryOver <>替换为实现System.Linq并简化查询的Query <>。

然后,您只需对.linq管理.Distinct()。无需陷入不必要的复杂性!

请注意,您只能加入在映射中定义的关系。