简体   繁体   中英

LINQ: Filter by value in sub list

I have obtained a list like this:

int[] listOfUserIds = new int[]{1,2,5};

var groups = db.some_table.Where(x => x.isOpen == true)
                        .Select(t => new Models.XModel() {
                            Id = t.Id,
                            Name = t.name,
                            Users = t.Users.Where(x => x.Age > 25).Select(user => new Models.UsersModel()
                            {
                                Name = user.Name,
                                UserId = user.UserId
                            })
                        });

Now from this groups list I would like to get the records where there is atleast one user whose UserId is within listOfUserIds .

How to achieve this easily without for loop?

Add 1 more condition to your Where clause:

x.Users.Any(user => listOfUserIds.Contains(user.UserId))

Your code:

var groups = db.some_table.Where(x => x.isOpen == true && x.Users.Any(user => listOfUserIds.Contains(user.UserId)))
                        .Select(t => new Models.SomeModel() {
                            Id = t.Id,
                            Name = t.name,
                            Users = t.Users.Where(x => x.Age > 25).Select(user => new Models.UsersModel()
                            {
                                Name = user.Name,
                                UserId = user.UserId
                            })
                        });

To improve performance, you can build a HashSet<int> :

int[] listOfUserIds = new int[]{1,2,5};
HashSet<int> hash = new HashSet<int>(listOfUserIds);

var groups = db.some_table.Where(x => x.isOpen == true && x.Users.Any(user => hash.Contains(user.UserId)))
                            .Select(t => new Models.SomeModel() {
                                Id = t.Id,
                                Name = t.name,
                                Users = t.Users.Where(x => x.Age > 25).Select(user => new Models.UsersModel()
                                {
                                    Name = user.Name,
                                    UserId = user.UserId
                                })
                            });

With HashSet<int> , this operation hash.Contains(x.Id) is O(1) instead of O(n) with listOfUserIds

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM