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();
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();