Home > database >  Filter record based on child list
Filter record based on child list

Time:03-11

I want to filter the record based on the child list. This is my code:

public class test1
{
    public int id { get; set; }
    public string name { get; set; }
    public string[] groupcode { get; set; }
    public List<test2> listtest2 { get; set; }
}

public class test2
{
    public string groupcode { get; set; }
}

List<test1> listtest1 = new List<test1>();
listtest1.Add(new test1() { id = 1, name = "Rule 1", listtest2 = new List<test2>() { new test2() { groupcode = "gr1" }, new test2() { groupcode = "gr2" }, new test2() { groupcode = "gr3" } } });
listtest1.Add(new test1() { id = 2, name = "Rule 2", listtest2 = new List<test2>() { new test2() { groupcode = "gr1" }, new test2() { groupcode = "gr2" }, new test2() { groupcode = "gr3" } } });
listtest1.Add(new test1() { id = 3, name = "Rule 3", listtest2 = new List<test2>() { new test2() { groupcode = "gr1" }, new test2() { groupcode = "gr2" }, new test2() { groupcode = "gr3" } } });
listtest1.Add(new test1() { id = 4, name = "Rule 4", listtest2 = new List<test2>() { new test2() { groupcode = "gr1" }, new test2() { groupcode = "gr2" }, new test2() { groupcode = "gr3" } } });
listtest1.Add(new test1() { id = 5, name = "Rule 5", listtest2 = new List<test2>() { new test2() { groupcode = "gr2" }, new test2() { groupcode = "gr3" } } });
listtest1.Add(new test1() { id = 6, name = "Rule 6", listtest2 = new List<test2>() { new test2() { groupcode = "gr2" }, new test2() { groupcode = "gr3" } } });
listtest1.Add(new test1() { id = 7, name = "Rule 7", listtest2 = new List<test2>() { new test2() { groupcode = "gr2" }, new test2() { groupcode = "gr3" } } });
listtest1.Add(new test1() { id = 8, name = "Rule 8", listtest2 = new List<test2>() { new test2() { groupcode = "gr2" }, new test2() { groupcode = "gr3" } } });

I have tried this but it gives me zero records. Can you please help me out?

var list = listtest1.Where(x => x.listtest2.Contains(new test2() { groupcode = "gr1" })).ToList();

Thanks in advance.

CodePudding user response:

Use .Any() to check listtest2 contains any item with groupcode is "gr1".

var list = listtest1
        .Where(x => x.listtest2.Any(y => y.groupcode == "gr1" ))
        .ToList();

Sample Program

CodePudding user response:

Since your test2 is defined as a class that's why Contains checks referential equality.

If you want to stick with your filtering logic then you have two options:

Define test2 as struct

public struct test2
{
    public string groupcode { get; set; }
}

In this case the comparison will based on value.

Implement IEqualityComparer interface

public class Test2Comparer : IEqualityComparer<test2>
{
    public bool Equals(test2? x, test2? y)
        => x.groupcode.Equals(y.groupcode);

    public int GetHashCode([DisallowNull] test2 obj)
        => obj.GetHashCode();
}

If you pass an instance of this class as a second parameter to the Contains then it will also work fine.

var filter = new test2() { groupcode = "gr1" };
var list = listtest1
           .Where(x => x.listtest2.Contains(filter, new Test2Comparer()))
           .ToList();
  • Related