LINQ检查列表<t>是否是另一个列表<t>的子集

时间:2015-10-20 06:54:10

标签: c# linq

我有两个Users类列表,即UsersExisting,UsersToUpdate。 类结构如下所示。

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的所有角色详细信息。

EG。这是清单

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

这是抛出错误。

3 个答案:

答案 0 :(得分:0)

我认为你在这里寻找的扩展方法是相交 - 在你的情况下,你希望得到的结果没有显示它在超级列表中不存在

if(!UsersToUpdate.AvailableRoles.Intersect(UsersExisting.AvailableRoles).Any())
{
      //your code here    
}

答案 1 :(得分:0)

由于您的列表是Role个对象的列表,因此您可能不想使用Contains(或Except),因为这只会告诉您是否那些特定对象实例在列表中 - 换句话说,它比较对象引用,而不是对象内容。 (除非,就是你改变了#34;等于&#34;对于你的班级来说,按照@ poke的答案)。

但是,我认为角色的Serial属性是您可以用于此目的的唯一标识符 - 在这种情况下,您可以执行以下操作:

bool isUsersUpdated = !UsersExisting.AvailableRoles.Select(r => r.Serial)
                      .Except(UsersToUpdate.AvailableRoles.Select(r => r.Serial))
                      .Any();

(虽然我个人会以不同方式构建查询)。

答案 2 :(得分:0)

不幸的是,你的问题仍然相当不完整。你没有说你到达那里的错误。所以这是一个有效的例子。请注意,正如Mrinal Kamboj所提到的,您需要为自定义类型实施EqualsGetHashCode,以便将其过滤掉:

List<Roles> existing = new List<Roles>
{
    new Roles(1, "admin", true),
    new Roles(2, "hr", false),
    new Roles(3, "it", true)
};
List<Roles> available = new List<Roles>
{
    new Roles(1, "admin", true),
    new Roles(2, "hr", false),
    new Roles(3, "it", true),
    new Roles(4, "finance", false)
};

bool isUsersUpdated = !existing.Except(available).Any();
Console.WriteLine(isUsersUpdated);


// modified Roles class
class Roles
{
    public int Serial { get; set; }
    public string Name { get; set; }
    public bool IsActive { get; set; }

    public Roles(int serial, string name, bool isActive)
    {
        Serial = serial;
        Name = name;
        IsActive = isActive;
    }

    public override bool Equals(object obj)
    {
        Roles other = obj as Roles;
        if (other == null)
            return false;
        return Serial == other.Serial && Name == other.Name && IsActive == other.IsActive;
    }

    public override int GetHashCode()
    {
        return new { Serial, Name, IsActive }.GetHashCode();
    }
}