Reputation: 3580
I have some classes modeling a guest user account and among others the guest's state and the guest's host:
public class GuestUser
{
public string LoginID {get; set;}
public List<GuestDetails> GuestDetailsList {get; set;}
}
public class GuestDetails
{
public GuestGroupUserState State {get; set;}
public GuestCreator GuestCreator {get; set;}
public GuestUser GuestUser {get; set;}
}
public class GuestCreator
{
public string CreatorLoginID {get; set;}
public List<GuestDetails> GuestDetailsList {get; set;}
}
public enum GuestGroupUserState
{
Unknown = 0,
Active = 1,
Locked = Active << 1,
Deleted = Locked << 1
}
I want to find all GuestUsers
and the respective GuestDetails
for a given GuestCreator gc
that are not in Deleted
-State.
So far, I tried
var guestUsers = gc.GuestDetailsList
.Where(gd => gd.State != GuestGroupUserState.Deleted)
.Select(gd => gd.GuestUser);
but this obviously gives me all the GuestDetails
for the users, also the ones in Deleted
state.
Next, I tried with
var guestUsers = userRepo.GuestUsers
.Where(gu => gu.GuestDetails
.Any(gd => gd.State != GuestGroupUserState.Deleted && gd.GuestCreator.Equals(gc)));
but again this gives me all GuestDetails
for these users, including the ones in Deleted
-state.
Is there a way to get all GuestUser
s that have a GuestDetail
in non-deleted state and for these users, get only the non-deleted GuestDetail
s? If a GuestUser
has only deleted details, it shouldn't appear in the list at all. At the moment, I'm foreach()
ing through my user lists generated with the code snippets above and removing the mismatched details entries from each guest - not the most efficient way I think.
Upvotes: 0
Views: 622
Reputation: 19210
This "isn't possible" in a strict sense. You can't "filter" the child collections; you need to allocate new ones:-
var guestUsers = ...; // Wherever they're coming from
var filteredUsers = guestUsers
.Where(x => x.GuestDetails.Any(y => y.State != GuestGroupUserState.Deleted))
.Select(x => new GuestUser()
{
LoginId == x.LoginId,
GuestDetails == x.GuestDetails
.Where(y => y.State != GuestGroupUserState.Deleted)
.ToList()
});
Or you might instead want to add a property to your GuestUser
object:-
public List<GuestDetails> ActiveGuestDetailsList
{
get { return this.GuestDetailsList.Where(y => y.State != GuestGroupUserState.Deleted); }
}
If you're using EF or similar you'll want to perform the filtering on the database and project onto a DTO instead.
Upvotes: 2
Reputation: 1613
With your current model architecture, you can't get rid of GuestUser
's deleted GuestDetails
on the GuestDetailsList
. To achieve your goal, you'll need to change the
public List<GuestDetails> GuestDetailsList {get; set;}
to:
public GuestDetails GuestDetails {get; set;}
on your GuestUser class. With a one-to-one relationship between GuestUser
and GuestDetails
you won't have such problems and will be able to get the correct information via:
var guestUsers = gc.GuestDetailsList
.Where(g => g.State != GuestGroupUserState.Deleted)
.Select(g => g.GuestUser);
Upvotes: 1