Filtering records with IEnumerable.Select
Asked Answered
M

2

9

In ASP.NET MVC 4 project, I have a model for join (with payload):

public class LeagueMember
{
    [Key, Column(Order = 0)]
    public int MemberId { get; set; }

    [Key, Column(Order = 1)]
    public int LeagueId { get; set; }

    public bool? IsActive { get; set; }

    [Required]
    public virtual League League { get; set; }

    [Required]
    public virtual Member Member { get; set; }

}

I am trying to pull all the active members of the league. So, in League model, I created a property like this:

public virtual ICollection<LeagueMember> LeagueMembers { get; set; }

public IEnumerable<Member> GetActiveMembers
{
    get
    {
        return LeagueMembers.Select(a => a.IsActive == true ? a.Member : null);
    }
}

But it looks like it returns a collection with size equals to that of all Members (with null values for the inactive members).

Is there a better way to apply filter in anonymous method to avoid nulls?

Morbidity answered 26/4, 2013 at 2:50 Comment(0)
E
4

Just remove your ternary condition within Select Method.

public IEnumerable<Member> GetActiveMembers
{
    get
    {
        return from activeMember in LeagueMembers
               where activeMember.IsActive == true
               select activeMember.Member;
        //return LeagueMembers.Select(a => a.IsActive == true);
    }
}
Eringo answered 26/4, 2013 at 2:54 Comment(3)
We need to return .Member, not .IsActive (bool).Morbidity
See my edit if you want to get the list of .Member property of the enumerated object in the LeagueMembers.Eringo
I noticed this reply uses the declarative syntax. IMO this is a non-solution to a non-problem that only bloats the documentation and adds confusion to examples, explanations, usage. In fact that's the general consensus now Too bad MS doesn't have that clarity of forethought. P.S. you really do not need "== true", it's clearly a Boolean expression.Sentimental
H
13

But it looks like it returns a collection with size equals to that of all Members (with null values for the inactive members).

Because you are specifically telling it do so. In your code you are telling the query to return a Member instance is the member is active OR a null if the member is NOT active.

return LeagueMembers.Select(a => a.IsActive == true ? a.Member : null);

You can go away with the ? expression and simply do a:

return LeagueMembers
    .Where(a => a.IsActive.GetValueOrDefault(false))
    .Select(o=>o.Member);
Halfprice answered 26/4, 2013 at 2:52 Comment(8)
IsActive is nullable Boolean. It should be a.IsActive == true. Plus it returns LeagueMember not Member list.Morbidity
"I am trying to pull all the active members of the league. " - Then your Member should have the IsActive property.Halfprice
"Then your Member should have the IsActive property". Active member of the league not just Active member. So IsActive must be present in LeagueMember.Morbidity
See my updated answer, I think that's why you need. And seriously people, why a downvote?Halfprice
Thanks! that worked. I really admire the nifty way of checking IsActive :-)Morbidity
Yeah, well I guess I was a minute late in understanding completely your issue and editing my answer so it get accepted. Well, the important thing is, your problem got solved and you learned something new.Halfprice
Why the fancy .GetValueOrDefault(false) rather than a.IsActive == true?Dollydolman
upvoting this answer because .Where() is the idiomatic way to do this.Petronilapetronilla
E
4

Just remove your ternary condition within Select Method.

public IEnumerable<Member> GetActiveMembers
{
    get
    {
        return from activeMember in LeagueMembers
               where activeMember.IsActive == true
               select activeMember.Member;
        //return LeagueMembers.Select(a => a.IsActive == true);
    }
}
Eringo answered 26/4, 2013 at 2:54 Comment(3)
We need to return .Member, not .IsActive (bool).Morbidity
See my edit if you want to get the list of .Member property of the enumerated object in the LeagueMembers.Eringo
I noticed this reply uses the declarative syntax. IMO this is a non-solution to a non-problem that only bloats the documentation and adds confusion to examples, explanations, usage. In fact that's the general consensus now Too bad MS doesn't have that clarity of forethought. P.S. you really do not need "== true", it's clearly a Boolean expression.Sentimental

© 2022 - 2024 — McMap. All rights reserved.