Вернуть уникальные результаты при использовании findAllBy - PullRequest
2 голосов
/ 31 августа 2011

У меня есть следующий метод в службе, обратите внимание на .user в строке def usersByRole:

def getUsersByRole(String desiredRole1, String desiredRole2, String desiredRole3) {
    Role role1 = Role.findByAuthority(desiredRole1)
    Role role2 = Role.findByAuthority(desiredRole2)
    Role role3 = Role.findByAuthority(desiredRole3)
    def usersByRole = UserRole.findAllByRoleInList([role1, role2, role3]).user
    return usersByRole
}  

Это работает хорошо, но когда у пользователя несколько ролей (т. Е. ROLE_ADMIN и ROLE_OWNER), этот пользователь существует дважды в коллекции, если обе из ранее упомянутых ролей заданы в качестве параметров. Есть ли какой-нибудь чистый способ заставить коллекцию содержать только уникальные результаты?

Ответы [ 2 ]

13 голосов
/ 31 августа 2011

Вопрос, аналогичный вашему, можно найти здесь: GORM createCriteria и list не возвращают одинаковые результаты: что я могу сделать?

Метод 1

Есливы хотите вернуть уникальный список пользователей непосредственно из запроса к БД, тогда вы можете использовать listDistinct на User (предположим, что у пользователя есть roles связь OneToMany с UserRoles)

User.createCriteria().listDistinct {
    roles {
       in 'role', [role1, role2, role3]
    }
}

Метод 2

Вы также можете попробовать запросить UserRole напрямую и сгруппировать пользователя, используя groupProperty (см. http://www.grails.org/doc/latest/ref/Domain%20Classes/createCriteria.html)

Метод 3

Удаление дублированных пользователей из возвращенныхсписок:

UserRole.findAllByRoleInList([role1, role2, role3])*.user.unique()
2 голосов
/ 31 августа 2011

Искатель вернет List, а вызов .user также вернет List, но вы можете обмануть и привести его к Set, и он удалит дубликаты. Поскольку нет необходимости в заказе (вы возвращаете def, поэтому не похоже, что вы заботитесь о типе коллекции), вам не нужно преобразовывать его обратно:

def getUsersByRole(String desiredRole1, String desiredRole2, String desiredRole3) {
    Role role1 = Role.findByAuthority(desiredRole1)
    Role role2 = Role.findByAuthority(desiredRole2)
    Role role3 = Role.findByAuthority(desiredRole3)
    return UserRole.findAllByRoleInList([role1, role2, role3]).user as Set
}

Это предполагает, что у вас есть четко определенные equals и hashCode в вашем классе User, поэтому проверка уникальности имеет смысл.

...