LINQ contains exactly matching


LINQ contains exactly matching



We have the following class structure and want to query all user who has at least all roles or more from the mustHaveRole Queryparameter.
If someone has a good idea that would be cool :-)


public class User
{
public Guid UserId { get; set; }
public string Username { get; set; }
public ICollection<UserRole> Roles { get; set; } = new HashSet<UserRole>();
}

public class UserRole
{
public virtual User User { get; set; }
public Guid UserId { get; set; }

public virtual Role Role { get; set; }
public Guid RoleId { get; set; }
}

public class Role
{
public Guid RoleId { get; set; }
public string RoleName { get; set; }
public ICollection<User> Users { get; set; } = new HashSet<User>();
}

public class QueryHandler
{
readonly List<User> Users = new List<User>();

public IEnumerable<User> Handle(List<Guid> musthaveRoles)
{
var queryResult =
from u in Users
from r in u.Roles
where musthaveRoles.Contains(r.RoleId) //ContainsAllExact and not has one of the roles???
select u;

return queryResult;
}
}




2 Answers
2



If you need an exact match you can use SequenceEqual method. To make it work you need to order your ids


SequenceEqual


ids


public IEnumerable<User> Handle(List<Guid> musthaveRoles)
{
var queryResult = Users.Where(
u => u.Roles.Select(r => r.RoleId).OrderBy(id => id)
.SequenceEqual(musthaveRoles.OrderBy(id => id)));

return queryResult;
}



This query will return only users who have exact same roles you expect and will filter out users who have more roles





the users with more roles should be also in the queryResult



You can use Intersect method:


Intersect


public IEnumerable<User> Handle(List<Guid> musthaveRoles)
{
var queryResult = Users.Where(u => u.Roles.Select(r => r.RoleId)
.Intersect(musthaveRoles).Count() == musthaveRoles.Count);
return queryResult;
}



Check a demo





cool, but the users with more roles should be also in the queryResult
– Jorgenson
Jun 30 at 8:10





I extended the userobject with a collection of status. In the many to many relation they have a status value. my question is: how can we filter the users with the queried status and a minimum statusvalue. demo dotnetfiddle.net/CCVwEP
– Jorgenson
Jun 30 at 12:21






@Jorgenson it would be better if you create a new question for this. You can link this question with a new one or just copy example from net fiddle into new question
– Aleks Andreev
Jun 30 at 12:32



I think what you are looking for is this:


var queryResult = Users.Where(x => musthaveRoles.All(y => x.Roles.Select(z => z.RoleId).Contains(y)));

// or this way
var queryResult1 = Users.Where(x => !musthaveRoles.Except(x.Roles.Select(y => y.RoleId)).Any());






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

.

How to generate build files in next js

Delphi Android file open failure with API 26