NHibernate QueryOver удалить дубликаты - PullRequest
0 голосов
/ 13 октября 2018

Я работаю в системе каналов, где мне нужно показать определенное количество каналов, а затем показать больше, нажав кнопку «Загрузить еще».

Итак, я определил количество строк дляизвлекать из базы данных (брать), и каждый раз, когда я нажимаю кнопку «Загрузить еще», я отправляю номер пропуска (количество уже показанных каналов).Проблема в том, что я получаю дублированные строки с моим запросом.

Я хочу использовать что-то вроде 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

Что работает, если я запускаю его непосредственно в БД, но когда я запускаю программу, она выдает это исключение

индекс был за пределами массива

Надеюсьне знаю что делать, помогите !!!!

1 Ответ

0 голосов
/ 13 октября 2018

Импорт nHibernate.Linq Замените QueryOver <> на Query <>, который реализует System.Linq и упростит ваш запрос.

Тогда вы просто введете admin .Distinct () в свой linq.Не нужно вдаваться в ненужные сложности!

Обратите внимание, что вы можете объединять только те отношения, которые вы определили в отображении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...