0

I am having two list of Users class i.e UsersExisting, UsersToUpdate. Class Structure is like below.

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}
}

I have to check whether UsersToUpdate has already all the Role details of UsersExisting.

Eg. This is the list

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}};

How to do this with LINQ.

I am doing like this.

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

This is throwing error.

Veer
  • 1,575
  • 3
  • 16
  • 40
  • `users_true list is subset of users` - Seems to me the other way around, users is a subset of users_true. – Maarten Oct 20 '15 at 06:56
  • 5
    Check this question and answer: [link](http://stackoverflow.com/q/332973/261050) – Maarten Oct 20 '15 at 06:57
  • What data types you are using? What is `{1,admin,true}`? Provide class description and show us your attempt. There is only some pseudo-code. We cannot reproduce your issue – Sergey Berezovskiy Oct 20 '15 at 06:57
  • I don't think that link totally answers question. We even don't know what code OP using currently and what problem he has. Voting for close – Sergey Berezovskiy Oct 20 '15 at 06:59
  • This should be simple in general, all that you need is whether a given subset elements are there in the parent collection, check this link too: http://stackoverflow.com/questions/12656582/linq-query-to-find-if-items-in-a-list-are-contained-in-another-list However please remember except the simple types like int, string, you have to override object method's Equals and GetHashCode for valid subset comparison – Mrinal Kamboj Oct 20 '15 at 07:16
  • @Sergey Have added all the details. – Veer Oct 20 '15 at 10:02

3 Answers3

0

I think the extension method you are looking for here is the Intersect - in your situation you are looking to get no results back to show that it doesn't exist in the super list

if(!UsersToUpdate.AvailableRoles.Intersect(UsersExisting.AvailableRoles).Any())
{
      //your code here    
}
Adam Stewart
  • 1,983
  • 1
  • 18
  • 25
0

Since your lists are lists of Role objects, you probably don't want to use Contains (or Except) since that will only tell you whether those specific object instances are in the list - in other words, it compares the object references, not the object contents. (Unless, that is, you change the meaning of "equals" for your class, per @poke's answer).

However, I imagine that the Serial property of a Role is a unique identifier that you can use for this purpose - in which case you can do something like this:

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

(Although personally I would structure the query differently).

Gary McGill
  • 26,400
  • 25
  • 118
  • 202
0

Unfortunately, your question is still rather incomplete. You didn’t say waht error you get there. So here’s a working example. Note that as Mrinal Kamboj mentioned, you need to implement Equals and GetHashCode for your custom type in order to filter them out:

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();
    }
}
poke
  • 369,085
  • 72
  • 557
  • 602