LINQ包含完全匹配

时间:2018-06-30 07:20:21

标签: c# entity-framework linq

我们具有以下类结构,并且要从mustHaveRole Queryparameter查询具有至少所有角色或更多角色的所有用户。 如果有人有一个好主意,那就好了:-)

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 个答案:

答案 0 :(得分:0)

如果需要完全匹配,可以使用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;
}

此查询将仅返回与您期望的角色完全相同的用户,并将过滤出具有更多角色的用户


编辑:

  

具有更多角色的用户也应位于queryResult

您可以使用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;
}

检查demo

答案 1 :(得分:0)

我认为您正在寻找的是这个

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());