0

I need to filter my data based on a Boolean condition using Linq on ASP.NET Web Api 2 C#. But my JSON data returns null when I try filtering the data.

The data is a List of Invites, I want to filter the results based on a MemberID and if the user is attending(IsAttending)

Here is the Member Model

public class Member
{
    public int MemberID { get; set; }
    public string MemberName { get; set; }
    public bool IsAdmin { get; set; }
    public bool IsAttending { get; set; }
    public int MemberNumber { get; set; }
    public string PhoneNumber { get; set; }
    public int InviteID { get; set; }
    [JsonIgnore]
    public virtual Invite Iinvite { get; set; }
}

InviteModel

public class Invite
{
    public int InviteID { get; set; }
    public string Subject { get; set; }
    public string DateTime { get; set; }
    public virtual List<Member> Members { get; set; }
}

Original JSON data without filtering

[{
    "InviteID": 1,
    "Subject": "Hell",
    "DateTime": "March 2017",
    "Members": [{
        "MemberID": 1,
        "MemberName": "roger",
        "IsAdmin": false,
        "IsAttending": false,
        "MemberNumber": 0,
        "PhoneNumber": null,
        "InviteID": 1
    },
    {
        "MemberID": 2,
        "MemberName": "nkosi",
        "IsAdmin": false,
        "IsAttending": false,
        "MemberNumber": 0,
        "PhoneNumber": null,
        "InviteID": 1
    },
    {
        "MemberID": 3,
        "MemberName": "Mphile",
        "IsAdmin": false,
        "IsAttending": false,
        "MemberNumber": 0,
        "PhoneNumber": null,
        "InviteID": 1
    }]
},
{
    "InviteID": 2,
    "Subject": "Hell",
    "DateTime": "March 2018",
    "Members": [{
        "MemberID": 4,
        "MemberName": "roger",
        "IsAdmin": false,
        "IsAttending": false,
        "MemberNumber": 0,
        "PhoneNumber": null,
        "InviteID": 2
    },
    {
        "MemberID": 5,
        "MemberName": "nkosi",
        "IsAdmin": false,
        "IsAttending": false,
        "MemberNumber": 0,
        "PhoneNumber": null,
        "InviteID": 2
    },
    {
        "MemberID": 6,
        "MemberName": "Mphile",
        "IsAdmin": false,
        "IsAttending": false,
        "MemberNumber": 0,
        "PhoneNumber": null,
        "InviteID": 2
    }]
},
{
    "InviteID": 3,
    "Subject": "Hell",
    "DateTime": "Marchs 2017",
    "Members": [{
        "MemberID": 7,
        "MemberName": "Roger Nkosi",
        "IsAdmin": false,
        "IsAttending": true,
        "MemberNumber": 0,
        "PhoneNumber": null,
        "InviteID": 3
    },
    {
        "MemberID": 8,
        "MemberName": "nkosi",
        "IsAdmin": false,
        "IsAttending": false,
        "MemberNumber": 0,
        "PhoneNumber": null,
        "InviteID": 3
    },
    {
        "MemberID": 9,
        "MemberName": "Mphile",
        "IsAdmin": false,
        "IsAttending": false,
        "MemberNumber": 0,
        "PhoneNumber": null,
        "InviteID": 3
    }]
},
{
    "InviteID": 4,
    "Subject": "Hell",
    "DateTime": "Marchs 2017",
    "Members": [{
        "MemberID": 10,
        "MemberName": "Roger Nkosi",
        "IsAdmin": false,
        "IsAttending": true,
        "MemberNumber": 0,
        "PhoneNumber": null,
        "InviteID": 4
    },
    {
        "MemberID": 11,
        "MemberName": "nkosi",
        "IsAdmin": false,
        "IsAttending": true,
        "MemberNumber": 0,
        "PhoneNumber": null,
        "InviteID": 4
    },
    {
        "MemberID": 12,
        "MemberName": "Mphile",
        "IsAdmin": false,
        "IsAttending": true,
        "MemberNumber": 0,
        "PhoneNumber": null,
        "InviteID": 4
    }]
}]

Here is how I filter and return the data

return db.invites.Include("members").ToList()
                .Where(x => x.Members == db.members
                                .Where(xx => xx.IsAttending == true && xx.MemberID == 4)).ToList();
9
  • What is your expected result? Your LINQ query will never return any result because you are comparing collections by reference. Please add to your question an example of what will the Json look like after the filtering. Commented Jul 13, 2017 at 9:36
  • How can I put this? I want my JSON to be the same, but include members where the member id matches and the IsAttending == true Commented Jul 13, 2017 at 9:40
  • What happens if there are members with IsAttending both true and false for a specific invite? It's not clear how deep you want your result to be filtered, that's why I asked you to add your expected result inside the question. Commented Jul 13, 2017 at 9:42
  • If the member attribute IsAttending == false, that member wont be part of the return JSON data. Commented Jul 13, 2017 at 9:45
  • In the original JSON you never have IsAttending == true && MemberID == 4. Commented Jul 13, 2017 at 9:50

2 Answers 2

1

What you want is not impossible, is just not achievable with a single LINQ query to the DB.

Assuming memberId contains the id of the member you want to filter on:

var invites = db.invites.Include(i => i.Members).Where(i => i.Members.Any(m => m.IsAttending && m.MemberID == memberId)).ToList(); // db query
invites = invites.Select(i =>
    new Invite
    {
        DateTime = i.DateTime,
        InviteID = i.InviteID,
        Subject = i.Subject,
        Members = i.Members.Where(m => m.IsAttending && m.MemberID == memberId).ToList()
    }).ToList(); // this removes other members (in memory)

 return invites;
Sign up to request clarification or add additional context in comments.

1 Comment

I would just include Members in the first query, to avoid n+1 requests...
0

You should use the Linq Any() operator.

It will look something more like

return db.invites.Include("members").Where(x => x.Members.Any(xx => xx.IsAttending && xx.MemberID == 4).ToList()

By the way, I removed the ToList() after db.invites because that will cause the entire members collection to enumerate. Not sure how big your database is, but that would eventually be a problem.

1 Comment

This works, but the way I need the result is, it would return the invite if the (xx => xx.IsAttending && xx.MemberID == 4) returns true, but I need the users which (xx => xx.IsAttending && xx.MemberID == 4) == false to not be included in the result.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.