Search code examples
nhibernatecollectionsrestrictioncreatecriteria

NHibernate query collection


I have a users and roles table. A user can have multiple roles.

I want to grab all of the users without a specific role. The problem is if a user has 2 roles, one being the role we don't want, the user will still be returned.

public IList<User> GetUserByWithoutRole(string role)
    {
        return CreateQuery((ISession session) => session.CreateCriteria<User>()
            .CreateAlias("Roles", "Roles")
            .Add(!Restrictions.Eq("Roles.RoleDescription", role))
            .List<User>());
    }

The only solution I came up with was client side

public IEnumerable<User> GetUserByWithoutRole(string role)
        {
            return CreateQuery((ISession session) => session.CreateCriteria<User>()
                .CreateAlias("Roles", "Roles")
                .Add(!Restrictions.Eq("Roles.RoleDescription", role))
                .List<User>()).Where(u => u.Roles.FirstOrDefault(r => r.RoleDescription == role) == null);
        }

Anyone know of a better solution? Thanks!


Solution

  • Alternatively you can use Criteria API to create subquery

    var subquery = DetachedCriteria.For<Role>("role");
    subquery.Add(Restrictions.EqProperty("role.User.id", "user.id"))
        .SetProjection(Projections.Property("role.RoleDescription"));
    
    var users = session.CreateCriteria<User>("user")
        .Add(Subqueries.NotIn(role, subquery))
        .List<User>();