LINQ检查列表是否< role >是另一个列表<角色>的子集

本文关键字:列表 角色 子集 另一个 role 检查 是否 LINQ | 更新日期: 2023-09-27 18:18:39

我有两个列表的用户类即UsersExisting, userstouupdate。类结构如下:

public class Users
{
    public string Name{get;set;}
    public Roles[] AvailableRoles{get;set;}
}
class Roles
{
    public int Serial{get;set;}
    public string Name{get;set;}
    public bool IsActive{get;set;}
}

我必须检查UsersToUpdate是否已经有UsersExisting的所有角色详细信息。

。这是列表

UsersExisting.AvailableRoles={{1,"admin",true},{2,"hr",false},{3,"it",true}};
UsersToUpdate.AvailableRoles={{1,"admin",true},{2,"hr",false},{3,"it",true},{4,"finance",false}};

如何在LINQ中做到这一点

我是这样做的。

bool isUsersUpdated = !UsersExisting.AvailableRoles
.Except(UsersToUpdate.AvailableRoles).Any();

LINQ检查列表是否< role >是另一个列表<角色>的子集

您可以比较SerialExcept的数字,它们似乎是角色标识符:

IEnumerable<int> existingRoles = UsersExisting
    .SelectMany(u => u.AvailableRoles.Select(r => r.Serial));
IEnumerable<int> updatingRoles = UsersToUpdate
   .SelectMany(u => u.AvailableRoles.Select(r => r.Serial));
bool isUsersUpdated = !existingRoles.Except(updatingRoles).Any();

我必须比较序列号和名称。

,那么最好的方法是覆盖Roles中的Equals + GetHashCode,或者提供一个可以传递给Enumerable.Except的自定义IEqualityComparer<Roles>。另一种方法是使用我的代码,但选择一个包含串行+名称的匿名类型:

IEnumerable<int> existingRoles = UsersExisting
    .SelectMany(u => u.AvailableRoles.Select(r => new {r.Serial,r.Name}));
IEnumerable<int> updatingRoles = UsersToUpdate
    .SelectMany(u => u.AvailableRoles.Select(r => new {r.Serial,r.Name}));
bool isUsersUpdated = !existingRoles.Except(updatingRoles).Any();

您必须在类Roles中重写EqualsGetHashCode方法才能使此工作。这是因为Except使用这些方法来确定对象是否彼此相等。

查看如何重写这些方法:

https://msdn.microsoft.com/en-US/library/ms173147 (v = vs.80) . aspx

如果您想比较某些自定义数据类型的对象序列,请在类中实现IEquatable泛型接口。另外,你必须重写Roles类中的Equals和GetHashCode方法。

我在这里创建了这个。net提琴。您可以看到程序的输出。

using System;
using System.Linq;
using System.Collections.Generic;
public class Program
{
    public static void Main()
    {
        Console.WriteLine("Hello World");
        var availbleRoles = new List<Roles>();
        availbleRoles.Add(new Roles() { Serial = 1, Name = "Test 1", IsActive = true });    
        availbleRoles.Add(new Roles() { Serial = 2, Name = "Test 2", IsActive = true });    
        availbleRoles.Add(new Roles() { Serial = 4, Name = "Test 4", IsActive = true });    

        var updatedRoles = new List<Roles>();
        updatedRoles.Add(new Roles() { Serial = 1, Name = "Test 1", IsActive = true }); 
        updatedRoles.Add(new Roles() { Serial = 2, Name = "Test 2", IsActive = true }); 
        updatedRoles.Add(new Roles() { Serial = 3, Name = "Test 3", IsActive = true }); 
        updatedRoles.Add(new Roles() { Serial = 4, Name = "Test 4", IsActive = true });

        var roles = updatedRoles.Except(availbleRoles);
        foreach (var role in roles)
        {
            Console.WriteLine("Serial : " + role.Serial + " Name : " + role.Name);
        }
        bool isRoleUpdated = roles.Any();
        Console.WriteLine("Role Updated : " + isRoleUpdated);
    }
}
public class Roles : System.IEquatable<Roles>
{
    public int Serial {get; set;}
    public string Name {get;set;}
    public bool IsActive {get;set;}
    public bool Equals(Roles other)
    {
        //Check whether the compared object is null.
        if (Object.ReferenceEquals(other, null)) return false;
        //Check whether the compared object references the same data.
        if (Object.ReferenceEquals(this, other)) return true;
        //Check whether the products' properties are equal.
        return Serial.Equals(other.Serial) && Name.Equals(other.Name);
    }
    // If Equals() returns true for a pair of objects 
    // then GetHashCode() must return the same value for these objects.
    public override int GetHashCode()
    {
        //Get hash code for the Name field if it is not null.
        int hashRoleName = Name == null ? 0 : Name.GetHashCode();
        // Get hash code for the Serial field.
        int hashSerial = Serial.GetHashCode();
        //Calculate the hash code for the Role.
        return hashSerial ^ hashRoleName;
    }
}
public class Users
{
    public string Name {get;set;}
    public Roles[] AvailableRoles { get; set; }
}